Pandas 是核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。Pandas 的目标是成为 Python 数据分析实践与实战的必备高级工具,本文主要总结数据分析中pandas的常用方法
python 版本:python3.7 pandas版本:'2.7.0'
1.引入模块import pandas as pd import numpy as np2.数据生成 2.1Series
Series是带标签的一维数组,可存储整数、浮点数、字符串、Python 对象等类型的数据。轴标签统称为索引。
调用 pd.Series 函数即可创建 Series:
s = pd.Series(data, index=index)
上述代码中,data 支持以下数据类型:
- Python 字典
Series 按字典的插入顺序排序索引(python3.7)
data = {'a': 3, 'b': 1, 'c': 2} s = pd.Series(data) s
- 多维数组
data 是多维数组时,index 长度必须与 data 长度一致。没有指定 index 参数时,创建数值型索引,即 [0, ..., len(data) - 1]。
s = pd.Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
- 标量值(如,5)
data 是标量值时,必须提供索引。Series 按索引长度重复该标量值。
pd.Series(100., index=['a', 'b', 'c', 'd', 'e'])
Dataframe 是由多种类型的列构成的二维标签数据结构,类似于 Excel 、SQL 表,或 Series 对象构成的字典。Dataframe 是最常用的 Pandas 对象,与 Series 一样,Dataframe 支持多种类型的输入数据:
- 一维 ndarray、列表、字典、Series 字典
用多维数组字典、列表字典生成 Dataframe
多维数组的长度必须相同。如果传递了索引参数,index 的长度必须与数组一致。如果没有传递索引参数,生成的结果是 range(n),n 为数组长度。
data = {'A': [1., 2., 3., 4.], 'B': [4., 3., 2., 1.]} pd.Dataframe(data)
pd.Dataframe(data, index=['a', 'b', 'c', 'd'])
用列表字典生成 Dataframe (自动生成range索引)
data = [{'a': 1, 'b': 2}, {'a': 5, 'b': 10, 'c': 20}]
用 Series 字典或字典生成 Dataframe
生成的索引是每个 Series 索引的并集。先把嵌套字典转换为 Series。如果没有指定列,Dataframe 的列就是字典键的有序列表。
data = {'A': pd.Series([1., 2., 3.], index=['a', 'b', 'c']), 'B': pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])} df = pd.Dataframe(data) df
pd.Dataframe(data, index=['d', 'b', 'a'])
pd.Dataframe(data, index=['d', 'b', 'a'], columns=['A', 'B'])
用元组字典生成 Dataframe
元组字典可以自动创建多层索引 Dataframe。
pd.Dataframe({('a', 'b'): {('A', 'B'): 1, ('A', 'C'): 2}, ('a', 'a'): {('A', 'C'): 3, ('A', 'B'): 4}, ('a', 'c'): {('A', 'B'): 5, ('A', 'C'): 6}, ('b', 'a'): {('A', 'C'): 7, ('A', 'B'): 8}, ('b', 'b'): {('A', 'D'): 9, ('A', 'B'): 10}})
- 二维 numpy.ndarray
pd.Dataframe(np.random.randn(5,5))
3.数据读取 3.1pandas读取excel
pd.read_excel(io, sheet_name=0, header=0, names=None, index_col=None, usecols=None, squeeze=False,dtype=None, engine=None, converters=None, true_values=None, false_values=None, skiprows=None, nrows=None, na_values=None, parse_dates=False, date_parser=None, thousands=None, comment=None, skipfooter=0, convert_float=True, **kwds)
1、io,文件存储路径
io = /home/work/xxxx.xlsx
2、sheet_name,sheet名称
可以是整型数字、列表名或SheetN,也可以是上述三种组成的列表。
整型数字:目标sheet所在的位置,以0为起始,比如sheet_name = 1代表第2个工作表。
3、header, 用哪一行作列名
4、names, 自定义最终的列名
5、index_col, 用作索引的列
6、usecols,需要读取哪些列
7、squeeze,当数据仅包含一列
8、converters ,强制规定列数据类型
9、skiprows,跳过特定行
10、nrows ,需要读取的行数
11、skipfooter , 跳过末尾n行
3.2pandas读取csvpd.read_csv(filepath_or_buffer: Union[str, pathlib.Path, IO[~AnyStr]], sep=',', delimiter=None, header='infer', names=None, index_col=None, usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skipinitialspace=False, skiprows=None, skipfooter=0, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=True, parse_dates=False, infer_datetime_format=False, keep_date_col=False, date_parser=None, dayfirst=False, cache_dates=True, iterator=False, chunksize=None, compression='infer', thousands=None, decimal: str = '.', lineterminator=None, quotechar='"', quoting=0, doublequote=True, escapechar=None, comment=None, encoding=None, dialect=None, error_bad_lines=True, warn_bad_lines=True, delim_whitespace=False, low_memory=True, memory_map=False, float_precision=None)
filepath_or_buffer为第一个参数,没有默认值,也不能为空,根据Python的语法,第一个参数传参时可以不写参数名。可以传文件路径:
3.3pandas连接mysql,并读取数据要实现 pandas 对 mysql 的读写需要三个库
- pandas
- sqlalchemy
- pymysql
1、read_sql_query 读取 mysql
read_sql_query 或 read_sql 方法传入参数均为 sql 语句,读取数据库后,返回内容是 dateframe 对象。
import pandas from sqlalchemy import create_engine class mysqlconn: def __init__(self): mysql_username = 'root' mysql_password = '123456' # 填写真实数库ip mysql_ip = 'x.x.x.x' port = 3306 db = 'work' # 初始化数据库连接,使用pymysql库 self.engine = create_engine('mysql+pymysql://{}:{}@{}:{}/{}'.format(mysql_username, mysql_password, mysql_ip, port,db)) # 查询mysql数据库 def query(self,sql): df = pandas.read_sql_query(sql,self.engine) # df = pandas.read_sql(sql,self.engine) 这种读取方式也可以 # 返回dateframe格式 return df if __name__ =='__main__': # 查询的 sql 语句 SQL = '''select * from working_time order by id desc ''' # 调用 mysqlconn 类的 query() 方法 df_data = mysqlconn().query(sql=SQL)
2、to_sql 写入数据库
使用 to_sql 方法写入数据库之前,先把数据转化成 dateframe 。
import pandas from sqlalchemy import create_engine class mysqlconn: def __init__(self): mysql_username = 'root' mysql_password = '123456' # 填写真实数库ip mysql_ip = 'mysql.mall.svc.test.local' port = 3306 db = 'work' # 初始化数据库连接,使用pymysql库 self.engine = create_engine('mysql+pymysql://{}:{}@{}:{}/{}'.format(mysql_username, mysql_password, mysql_ip, port,db)) # 查询mysql数据库 def query(self,sql): df = pandas.read_sql_query(sql,self.engine) # df = pandas.read_sql(sql,self.engine) # 返回dateframe格式 return df # 写入mysql数据库 def to_sql(self,table,df): # 第一个参数是表名 # if_exists:有三个值 fail、replace、append # 1.fail:如果表存在,啥也不做 # 2.replace:如果表存在,删了表,再建立一个新表,把数据插入 # 3.append:如果表存在,把数据插入,如果表不存在创建一个表!! # index 是否储存index列 df.to_sql(table, con=self.engine, if_exists='append', index=False) if __name__ =='__main__': # 创建 dateframe 对象 df = pandas.Dataframe([{'name':'小米','price':'3999','colour':'白色'},{'name':'华为','price':'4999','colour':'黑色'}]) # 调用 mysqlconn 类的 to_sql() 方法 mysqlconn().to_sql('phonetest',df)3.4pandasl连接oracle,并去读数据
1、登录oracle
首先先导入sqlalchemy库的create_engine,
通过 engine = create_engine("dialect+driver://username:password@host:port/database")初始化连接
参数说明:
dialect,是数据库类型包括:sqlite, mysql, postgresql, oracle, mssql等
driver,指定连接数据库的API,如:`psycopg2``, ``pyodbc``, ``cx_oracle``等,为可选关键字。
username,用户名
password,密码
host,网络地址,可以用ip,域名,计算机名,当然是你能访问到的。
port,数据库端口。
database,数据库名称。
from sqlalchemy import create_engine engine = create_engine("oracle://scott:tiger@hostname/dbname",encoding='utf-8', echo=True)
2、read_sql
pd.read_sql(sql, con, index_col=None, coerce_float=True, params=None, parse_dates=None, columns=None, chunksize=None)
参数说明:
sql,执行的sql,可为查询、删除、创建、更新等等的sql,在此可直接指定表名称,默认就是select * from tablename
con,指定的数据库连接,即con=engine,也就是我们刚才初始化的数据库连接engine
index_col,查询时,指定那一列为Dataframe的index,也可以是多列['a','b'],此时就生成了Multindex
coerce_float,boolean,默认为True,尝试转换float的值,用于设置sql查询的结果
params,list, tuple or dict, 可选关键字, 默认为:None,要传递给执行方法的参数列表。不太懂这个关键字,一般情况用不到
parse_dates, list or dict, 默认为 None,要解析为日期时间的字段
columns,查询时指定选择那些列,即select * from 中的*,默认全部列
chunksize,int,默认为None,如果指定数值,则返回一个迭代器,指定的数值为迭代器内数据的行数
3、to_sql
Dataframe.to_sql(self, name, con, schema=None, if_exists='fail', index=True, index_label=None, chunksize=None, dtype=None)
4.数据查看关键参数说明:
name,数据库表名
con,指定的数据库连接,即con=engine,也就是我们刚才初始化的数据库连接engine
schema,指定样式,不明白有什么用处
if_exists,{'fail', 'replace', 'append'}, 默认为'fail',即指定当数据库表存在时的处理方式,默认为fail,挂起一个错误
* fail: 挂起一个错误
* replace: drop掉原来的表,重新创建
* append: 在原来表基础上插入数据index,boolean,默认为True,指定Dataframe的index是否一同写入数据库
index_label,在index关键字为True时,指定写入的index的字段名称,默认为None时,字段名称为index
chunksize,int,默认为None,如果指定数值,则返回一个迭代器,指定的数值为迭代器内数据的行数。当写入的数据量较大时,最好指定此关键字的数值
dtype,dict, 可选关键字,默认为None,即指定写入的字段字符类型,注意做好指定字符类型,因默认写入的数据类型数是colb,若没有指定数据类型,估计会报错。
dates = pd.date_range('20210101', periods=20) df = pd.Dataframe(np.random.randn(20, 4), index=dates, columns=list('ABCD'))4.0显示设置
pd.set_option('display.max_rows',500)#设置展示最高行数 pd.set_option('display.max_columns',1000)#设置展示最高列数 pd.set_option('display.unicode.east_asian_width',True)#设置列名对齐 ————————————————4.1查看前几行数据
df.head()4.2查看前几行数据
df.tail()4.3查看dataframe的形状
df.shape
4.4数据表基本信息(维度、列名称、数据格式、所占空间等)(20, 4)
df.info()
4.5每一列数据的格式DatetimeIndex: 20 entries, 2021-01-01 to 2021-01-20 Freq: D Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 A 20 non-null float64 1 B 20 non-null float64 2 C 20 non-null float64 3 D 20 non-null float64 dtypes: float64(4) memory usage: 800.0 bytes
df.dtype
4.6某一列数据的格式A float64 B float64 C float64 D float64 dtype: object
df['B'].dtype
4.7空值dtype('float64')
df.isnull()
df.isna()
4.8某一列空值
df['B'].isnull()
df['B'].isna()
isna()和 isnull()区别:
isnan判断是否nan(not a number),一般是数值字段的null
isnull()主要是判断字符型是否有值, 可以判断所有的空值,但是python的数值字段比如int float 为空的时候默认是Nan
4.9查看列名称可以看到isna()对,字符型空值不起作用
df.columns
4.10查看索引Index(['A', 'B', 'C', 'D', 'F'], dtype='object')
df.index
4.11查看某一列的唯一值DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', '2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08', '2021-01-09', '2021-01-10', '2021-01-11', '2021-01-12', '2021-01-13', '2021-01-14', '2021-01-15', '2021-01-16', '2021-01-17', '2021-01-18', '2021-01-19', '2021-01-20'], dtype='datetime64[ns]', freq='D')
df['F'].unique()
4.12查看统计信息array(['f', ''], dtype=object)
df.describe()5.数据筛选 5.1布尔索引
df[df['F'] == 'f'] # 判断等式是否成立5.2位置索引(iloc)
是根据行号来索引,行号从0开始,逐次加1
# 直接根据行号取值 df.iloc[1:2]5.3标签索引(loc)
# 直接根据索引取值 df.loc["2021-01-02":"2021-01-02"]
# 使用布尔 df.loc[df['A']==2]
不同:
1. loc函数通过调用index名称的具体值来取数据
2. iloc函数通过行序号来取数据
3. 取多行数据时iloc不包含末尾
4. 对数据进行筛选使用loc函数,当使用loc函数时,如果index不具有特定意义,而且重复,那么提取的数据需要进一步处理,可用.reset_index()函数重置
df.query('F=="f"')
# 多条件查询 df.query('A==1 | B==2')6.数据清洗 7.数据排序
Pandas 支持三种排序方式,按索引标签排序,按列里的值排序,按两种方式混合排序。
7.1 按索引标签排序Series.sort_index() 与 Dataframe.sort_index() 方法用于按索引层级对 Pandas 对象排序。
7.2 按值排序Series.sort_values()方法用于按值对 Series 排序。
‘Dataframe.sort_values() 方法用于按行列的值对 Dataframe 排序。
Dataframe.sort_values() 的可选参数 by 用于指定按哪列排序,该参数的值可以是一列或多列数据。
这些方法支持用 na_position 参数处理空值。
na_position='first'(空置排在前面)7.3 混合排序
通过参数 by 传递给 Dataframe.sort_values()的字符串可以引用列或索引层名。
7.4搜索排序Series 支持 searchsorted() 方法,这与numpy.ndarray.searchsorted() (opens new window)的 *** 作方式类似。7.5最大值与最小值
df.loc[:,'A'].nsmallest(3)
2021-01-01 0 2021-01-02 0 2021-01-03 0 Freq: D, Name: A, dtype: int64
df.loc[:,'A'].nlargest(3)
8.数据拼接 9.数据聚合 10.时间日期 11.函数应用2021-01-07 1 2021-01-08 1 2021-01-12 1 Name: A, dtype: int64
管是为 Pandas 对象应用自定义函数,还是应用第三方函数,都离不开以下三种方法。用哪种方法取决于 *** 作的对象是 Dataframe,还是 Series ;是行、列,还是元素。
-
表级函数应用:pipe()
-
行列级函数应用: apply()
-
聚合 API: agg() 与 transform()
-
元素级函数应用:applymap()
虽然可以把 Dataframe 与 Series 传递给函数,不过链式调用函数时,最好使用 pipe()方法。对比以下两种方式:
# f、g、h 是提取、返回 `Dataframes` 的函数 >>> f(g(h(df), arg1=1), arg2=2, arg3=3)
>>> (df.pipe(h) ... .pipe(g, arg1=1) ... .pipe(f, arg2=2, arg3=3))2、行列级函数应用
apply() 方法沿着 Dataframe 的轴应用函数,比如,描述性统计方法,该方法支持 axis 参数。
df.iloc[:,:4].apply(np.mean)
A 0.300000 B -0.054087 C 0.117827 D 0.020045 dtype: float64
df.iloc[:,:4].apply(np.mean, axis=1)
2021-01-01 -0.035445 2021-01-02 -0.713445 2021-01-03 0.081043 2021-01-04 0.002215 2021-01-05 -0.259167 2021-01-06 0.093416 2021-01-07 -0.190826 2021-01-08 -0.305420 2021-01-09 -0.024411 2021-01-10 0.486128 2021-01-11 0.303144 2021-01-12 0.186884 2021-01-13 0.325273 2021-01-14 0.397488 2021-01-15 0.478969 2021-01-16 0.247686 2021-01-17 0.351837 2021-01-18 0.650051 2021-01-19 0.071887 2021-01-20 -0.228385 Freq: D, dtype: float64
apply()方法还支持通过函数名字符串调用函数。
df.iloc[:,:4].apply('mean')
A 0.300000 B -0.054087 C 0.117827 D 0.020045 dtype: float64
df.iloc[:,:4].apply('mean',axis=1)
2021-01-01 -0.035445 2021-01-02 -0.713445 2021-01-03 0.081043 2021-01-04 0.002215 2021-01-05 -0.259167 2021-01-06 0.093416 2021-01-07 -0.190826 2021-01-08 -0.305420 2021-01-09 -0.024411 2021-01-10 0.486128 2021-01-11 0.303144 2021-01-12 0.186884 2021-01-13 0.325273 2021-01-14 0.397488 2021-01-15 0.478969 2021-01-16 0.247686 2021-01-17 0.351837 2021-01-18 0.650051 2021-01-19 0.071887 2021-01-20 -0.228385 Freq: D, dtype: float64
默认情况下,apply()调用的函数返回的类型会影响 Dataframe.apply 输出结果的类型。
-
函数返回的是 Series 时,最终输出结果是 Dataframe。输出的列与函数返回的 Series 索引相匹配。
-
函数返回其它任意类型时,输出结果是 Series。
result_type 会覆盖默认行为,该参数有三个选项:reduce、broadcast、expand。这些选项决定了列表型返回值是否扩展为 Dataframe。
apply()有一个参数 raw,默认值为 False,在应用函数前,使用该参数可以将每行或列转换为 Series。该参数为 True 时,传递的函数接收 ndarray 对象,若不需要索引功能,这种 *** 作能显著提高性能。
3、聚合 API聚合 API 可以快速、简洁地执行多个聚合 *** 作。Pandas 对象支持多个类似的 API,如 groupby API、window functions API、resample API 。聚合函数为Dataframe.aggregate() ,它的别名是 Dataframe.agg() 。
1AGG单函数聚合
应用单个函数时,该 *** 作与 apply() 等效,这里也可以用字符串表示聚合函数名。下面的聚合函数输出的结果为 Series:
df.iloc[:,:4].agg(np.mean)
A 0.300000 B -0.054087 C 0.117827 D 0.020045 dtype: float64
df.iloc[:,:4].agg(np.mean,axis=1)
2021-01-01 -0.035445 2021-01-02 -0.713445 2021-01-03 0.081043 2021-01-04 0.002215 2021-01-05 -0.259167 2021-01-06 0.093416 2021-01-07 -0.190826 2021-01-08 -0.305420 2021-01-09 -0.024411 2021-01-10 0.486128 2021-01-11 0.303144 2021-01-12 0.186884 2021-01-13 0.325273 2021-01-14 0.397488 2021-01-15 0.478969 2021-01-16 0.247686 2021-01-17 0.351837 2021-01-18 0.650051 2021-01-19 0.071887 2021-01-20 -0.228385 Freq: D, dtype: float64
Series 单个聚合 *** 作返回标量值:
df.loc[:,'A'].agg('sum')
6
多函数聚合
还可以用列表形式传递多个聚合函数。每个函数在输出结果 Dataframe 里以行的形式显示,行名是每个聚合函数的函数名。
df.iloc[:,:4].agg(['sum', 'mean'])
df.iloc[:,:4].agg(['sum', 'mean'],axis=1)
Series 聚合多函数返回结果还是 Series,索引为函数名:
df.loc[:,'A'].agg(['sum', 'mean'])
sum 6.0 mean 0.3 Name: A, dtype: float64
传递 lambda 函数时,输出名为
df.loc[:,'A'].agg(['sum', lambda x: x.mean()])
sum 6.00.3 Name: A, dtype: float64
应用自定义函数时,该函数名为输出结果的行名:
def mymean(x): return x.mean() df.loc[:,'A'].agg(['sum', mymean])
sum 6.0 mymean 0.3 Name: A, dtype: float64
用字典实现聚合
指定为哪些列应用哪些聚合函数时,需要把包含列名与标量(或标量列表)的字典传递给 Dataframe.agg。
注意:这里输出结果的顺序不是固定的,要想让输出顺序与输入顺序一致,请使用 OrderedDict。
df.agg({'A': 'mean', 'B': 'sum'})
A 0.300000 B -1.081742 dtype: float64
输入的参数是列表时,输出结果为 Dataframe,并以矩阵形式显示所有聚合函数的计算结果,且输出结果由所有唯一函数组成。未执行聚合 *** 作的列输出结果为 NaN 值:
df.agg({'A': ['mean', 'min'], 'B': 'sum'})
多种数据类型(Dtype)
与 groupby 的 .agg *** 作类似,Dataframe 含不能执行聚合的数据类型时,.agg 只计算可聚合的列(数值,字符串等类型)
2Transform APItransform()方法的返回结果与原始数据的索引相同,大小相同。与 .agg API 类似,该 API 支持同时处理多种 *** 作,不用一个一个 *** 作。
这里转换的是整个 Dataframe。.transform() 支持 NumPy 函数、字符串函数及自定义函数。
df.iloc[:,:4].transform(np.abs) df.iloc[:,:4].transform('abs') df.iloc[:,:4].transform(lambda x: x.abs())
.transform() 向 Series 传递单个函数时,返回的结果也是单个 Series。
多函数 Transform
transform() 调用多个函数时,生成多层索引 Dataframe。第一层是原始数据集的列名;第二层是 transform() 调用的函数名。
df.iloc[:,:4].transform([np.abs, lambda x: x + 1])
用字典执行 transform *** 作
df.iloc[:,:4].transform({'A': np.abs, 'B': lambda x: x + 1})
transform() 的参数是列表字典时,生成的是以 transform() 调用的函数为名的多层索引 Dataframe。
4、元素级函数应用
并非所有函数都能矢量化,即接受 NumPy 数组,返回另一个数组或值,Dataframe 的 applymap()及 Series 的 map(),支持任何接收单个值并返回单个值的 Python 函数。
Series.map() 还有个功能,可以“连接”或“映射”第二个 Series 定义的值。这与 merging / joining 功能 联系非常紧密:
12.数据输出
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)