目录
🔹 前言
pandas我认为是python库中最基础的数据分析工具,很多其他的高级数据分析库都是在它的基础上或者借鉴中开发的。无论是不是做数据分析的,学python不学pandas真的是一大憾事。本文章是一篇入文章,里面有最基本的使用方法,日常使用够用了,更详细的可以看官方文档。
pandas官方文档:API reference
一般没有特殊说明,文章中pd指的是pandas,np指的是numpy,df指的是dataFrame,se指的是series
🔹 安装使用
安装pandas
pip install pandas
文件中导入
import pandas as pd
🔹 数据导入
1、读取excel
pandas.read_excel("file:/....",sheet_name=0,header=0,names=[]) # 读取xls数据:
sheet_name
可以是数字,可以是列表,
header
是导入数据时,规定第几行是标题,值是数字和None
names
是自定义列名
2、读取数据库(sqlite数据库)
df=pd.read_sql("SELECT * from {} ".format("table_name"),conn_data)
注意第一个参数不是表名,SQL查询语句
3、读取CSV格式数据
CSV格式的数据是文本格式,可以直接用记事本打开,非常方便共享
pd.read_csv('./***.csv')
如果你的文本文件列与列之间是用多个空格或者制表符分隔,比较省事的代码:
pd.read_csv('./***.txt', sep='\s+', engine='python')
# \s+ 是一个正则表达式,它匹配一个或多个空格或制表符;
# engine='python' 指定使用Python解析器处理正则表达式。
4、读取pickle二进制格式数据
pd.read_pickle('./***.pickle')
🔹 数据导出
1、Numpy数据导出
df.to_numpy()
df.values
2、JSON格式导出
DataFrame.to_json( path_or_buf = None , orient = None )
to_json函数改两个参数即可,其余参数不常用
orient改变JSON输出的格式,一般常用的就是'split'
,'records'
这两个
>>> d=pd.DataFrame({"name":["a","b"],"age":[4,8]})
>>> d
name age
0 a 4
1 b 8
>>> d.to_json(orient="split") # 我非常喜欢这个,因为这种JSON格式非常容易使用JS转为html表格数据,前端福利!!!
'{"columns":["name","age"],"index":[0,1],"data":[["a",4],["b",8]]}'
>>> d.to_json(orient="records")
'[{"name":"a","age":4},{"name":"b","age":8}]'
3、数据存储在SQL数据库
一定要排序好,存储到数据库中,如果df的列名和数据库的字段名一致,会自动充填到数据库中。
df.to_sql("table",con=conn,if_exists="append",index=False)
if_exists
设置为"append",会将数据添加到数据库中
4、导出CSV格式数据
df.to_csv('./***.csv',sep='',index=False)
其中sep
是设置分割方式,index
设置为False
意思是导出的时候不要导出行标签
5、保存pickle二进制格式数据
df.to_pickle('./***.pickle')
🔹 Dataframe 常用函数
df.shape # 以元素的形式返回行和列
df.shape[1] # 查询列数
df.shape[0] # 查询行数
df.head(n) # 查看DataFrame对象的前n⾏
df.tail(n) # 查看DataFrame对象的最后n⾏
df.shape # 查看⾏数和列数,返回的是元组
df.info() # 查看索引、数据类型和内存信息
df.columns() # 查看字段(⾸⾏)名称
df.describe() # 查看数值型列的汇总统计
df.dtypes# 查看数据类型
df.T # 行和列转置
df.sort_values(by= ) # 排序数据
df["列名称"].unique() # 查看DataFrame对象中每⼀列的唯⼀值,去重操作
df.isnull().any() # 查看是否有缺失值
df.empty # 查看是否df是空的,返回true和false
df.hist() # 绘制直方图
df[df[column_name].duplicated()] # 查看column_name字段数据重复的数据信息(查重操作)
df[df[column_name].duplicated()].count() # 查看column_name字段数据重复的个数
🔹 Dataframe 设置
列名可以在实例化的时候通过columns
参数赋值。
索引可以在实例化的时候通过index
参数赋值(可以字符串也可以数字,默认是数字)
如果想修改列名和索引,可以通过一下方法来修改:
dataFrame.columns=[] # 可以直接修改列名,数量上需要与数据数量对应
dataFrame.index=[] # 可以直接修改索引,数量上需要与数据数量对应
使用reindex()
方法重新索引,更改行和列的顺序
>>> df
one two three
a 1.394981 1.772517 NaN
b 0.343054 1.912123 -0.050390
c 0.695246 1.478369 1.227435
d NaN 0.279344 -0.613172
>>> df.reindex(index=["c", "f", "b"], columns=["three", "two", "one"])
three two one
c 1.227435 1.478369 0.695246
f NaN NaN NaN
b -0.050390 1.912123 0.343054
简化重新索引
df[['A', 'D', 'C', 'B']]
如果想重新设置为0,1,2,3这样的索引,可以使用reset_index()
方法,返回的是副本,老的索引会变成一个新列,列名为index。
>>> data.reset_index()
index col1 col2
0 row1 1 3
1 row2 2 4
2 row2 2 4
🔹 列操作
1、选择
使用df["列名"]
来获取一列的series
,然后操作series就可以
>>> df
one two
a 1.0 1.0
b 2.0 2.0
c 3.0 3.0
d NaN 4.0
>>> df["one"]
a 1.0
b 2.0
c 3.0
d NaN
Name: one, dtype: float64
2、添加
像python字典一样赋值即可,
df["three"] = df["one"] * df["two"]
还有一些其他函数:loc()
、insert()
、concat()
,不过要注意赋值的时候用numpy数组或者普通列表。
3、删除
使用pop()
函数
需要注意的是删除是对原有数据的操作,不建议使用,删除前最好创建个副本
del df["two"]
df.pop("three")
使用drop
()函数
drop对原有数据不会修改,但是要指定轴axis=1
,才能删除列
df.drop(['col1'],axis=1)
🔹 行操作
1、添加
添加数值使用索引的时候直接赋值即可,但是类型、数量要对应。
df.loc["row3"]=[7,8]
df.iloc[2]=[7,8]
还有一种方法是使用append()
函数,注意有的时候需要添加ignore_index=True
才能添加一行
s = pd.Series([16, 17, 18, 19], index=df.columns)
df = df.append(s, ignore_index=True)
2、删除
使用pop()
/drop()
函数
🔹 索引/筛选
选择列
使用df["列名"]
来获取一列的series
如果要选择多列,可以使用df[['列1','列2']]
,传入的列名需要用列表包裹
选择行
1、切片选择
注意[]里面必须是切片,如果是单值,跟numpy不一样,不是选择某一行,会报错
>>> q.columns=["q","w"]
>>> q.index=["a","b"]
>>> q
q w
a 1 3
b 2 4
>>> q[0:1]
q w
a 1 3
2、loc选择
loc可以使用索引名称来选择行
>>> q.loc["a"]
q 1
w 3
Name: a, dtype: int64
3、iloc选择
iloc是用索引位置来选择行
>>> q.iloc[0]
q 1
w 3
Name: a, dtype: int64
混合选择
如果想选择特定的行以及列,可以使用df.loc[[行],[列]]
或者df.iloc[[行],[列]]
# 获取第一列的所有数据,使用了切片
df.loc[:,['第一列名称']]
# 获取3至5列
df.iloc[:,3:6]
高级筛选
逻辑筛选
pandas条件逻辑连接:且:&
,或:|
,大于:>
,小于:<
,等于:==
,不等于:!=
例:df[(df.A==100)&(df.B=='a')]
df.loc[df['drill']=='值',:] # 简写:df[df['drill']=='值',:]
df['drill']=='值'
返回的是series,数据类型是bool。
除了使用布尔series
外,还可以使用自己的布尔列表[True,False,True]
补充:pandas提供了一个函数:isin()
,返回是否有传入参数的布尔值,我认为用==
比较好
where筛选
pandas有where()函数,可以返回符合条件的数值,最重要的是返回的数据结构和初始的结构相同(这个和逻辑筛选不同)
>>> df
col1 col2
row1 1 3
row2 2 4
row3 7 8
>>> df.where(df>1)
col1 col2
row1 NaN 3.0
row2 2.0 4.0
row3 7.0 8.0
补充:设置函数where的第二个参数,可以将NaN替换为设置的参数。
query筛选
pandas有query()
函数,可以使用表达式来选择。
表达式支持逻辑运算符以外,还支持in
,not in
>>> df
a b c
0 7 8 9
1 1 0 7
2 2 7 2
3 6 2 2
>>> df.query('(a < b) & (b < c)')
a b c
0 7 8 9
>>> df[(df['a'] < df['b']) & (df['b'] < df['c'])]
a b c
0 7 8 9
>> # 以下是表达式的其他形式,输出结果都一样。
>>> df.query('a < b & b < c')
>>> df.query('a < b and b < c')
>>> df.query('a < b < c')
filter筛选
随机选择
df.sample(n=6, replace=True,weights=) # n为随机选择的数量,replace设置选择后能否再被选择,默认是False(不能被选择)
🔹 Dataframe排序
1、按索引排序
df.sort_index()
2、按值排序
df.sort_values()
要加参数by
🔹 数据类型
此节介绍pandas的数据类型,有关数据类型的处理请看 类型转换 一节
每一列的各个数据应该是相同的,如果数据类型不同,那么此列的数据类型就为object
pandas支持所有numpy数据类型:
float、 int、bool
dtype | 解释 |
---|---|
float | 浮点型 |
int | 整型 |
bool | 布尔 |
datetime64 | 日期 |
pandas还扩展了许多其他类型。
dtype | 解释 |
---|---|
category | 分类值,可以节约内存,对重复性的数据友好。 |
🔹 数据处理
1、数据缺失值处理
pandas中的缺失值用NAN
表示(nan忽略大小写)。nan是numpy的一个库,可以用numpy.nan
来使用。
使用pd.isnull()
或者notnull()
或者np.isnan()
来判断是否是空值。
注意: NAN不等于NAN,想判断是不是空值,需要用上面的函数方法判断
补充: pandas在统计时,会直接忽略缺失值
缺失值统计
np.count_nonzero(df.isnull) # 统计所有元素中的缺失值个数
np.count_nonzero(df["列名".isnull) # 统计某一列中缺失值个数
# 还可以使用value_counts()函数,但这个函数只能用于series,所以这个方法只能统计某一列中缺失值的个数
df["列名"].value_counts(dropna=False).head() # 如果dropna参数不设置为false的话,缺失值会丢失
''' 打印输出:
NaN 1
1.0 1
Name: col1, dtype: int64 '''
缺失值填充
使用fillna()
函数
# 用自定义数值填充
df.fillna(0,inplace=True) # 用0填充空值,修改原始数据
# 前值填充
df.fillna(method='ffill') # 缺失值使用前一行的数据填充,如果第一行就没有数据,那么缺失值数据会一直存在。
# 后值填充
df.fillna(method='bfill') # 最后一行没有数据,就尴尬了。
# 线性插值 等距插值
df.interpolate() # 但是那种有两个数据挨在一起的数据就无法插值了。
缺失值删除
df.dropna(axis=0)# 删除有NaN的是数据行,axis=0是删除行,axis=1是删除列
直接删除有缺失值的属性
df.drop("想删除的列名",axis=1) # 跟dropna一样,axis=0为行,为1是列
2、数据类型转换
astype(dtype,copy=True,errors=‘raises’, kwargs)** #转换类型,只能是相似类型之间转换
dtype
:表示数据的类型。
copy
:是否建立副本,默认为True。
errors
:错误采取的处理方式,可以取值为raise或ignore,默认为raise。其中raise表示允许引发异常,ingore表示抑制异常。
转成数字:
pd.to_numeric # 强制将对象转为数字。
转成日期:
pd.to_datetime(df['要转换的列'],format='%Y-%m-%d') #将类似于2020-12-25的日期字符串转为日期格式。
3、数据重复值处理
duplicated()
:返回布尔值series,True表示的“多余的”
drop_duplicates()
:删除“多余的”(即duplicated
返回True
的)重复值
DataFrame.duplicated(subset=None, keep='first')
DataFrame.drop_duplicates(subset=None, keep='first', inplace=False, ignore_index=False)
keep
参数解释:
keep=‘first’(默认):标记除第一次出现的重复项。(第一次出现的设为False,其余设置为True)
keep=‘last’:标记除最后一次出现的重复项。(最后一次出现的设为False,其余设置为True)
keep=False:标记所有重复项。(重复的全部设为True)
注意:
一定要仔细理解括号的意思,我刚开始学习的时候,pandas的keep参数弄反了,keep翻译为“保留”,pandas的first指的是设置第一个为False
>>> df
a b c
0 one x -1.067137
1 one y 0.309500
2 two x -0.211056
3 two y -1.842023
4 two x -0.390820
5 three x -1.964475
6 four x 1.298329
>>> df2.duplicated('a')
0 False
1 True
2 False
3 True
4 True
5 False
6 False
dtype: bool
🔹 数据整理
逆透视
pandas.melt(frame, id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None, ignore_index=True)
从宽格式转为长格式
透视
函数应用: apply()
apply()简直就是一个神器,使用他就不用使用迭代方法对每一个参数操作,代码写的更少了。
该方法有一个func参数,当传递给它一个函数之后,apply()
方法就会把传入的函数应用于Series的每个元素。而且apply里可以加附加参数,func有多个参数的时候,可以使用附加参数占位
def my_exp(x,e):
return x**e
df["col1"].apply(my_exp,e=2)
对dataframe操作时,有axis参数(默认为0,对列方向操作,结果也是按列返回,返回的是dataframe),func中传入的是axis方向的列表:
你如果想一行一行处理的话,需要将axis设置为1,但是结果返回的series,需要自己处理一下变成dataframe。
def avg_3_apply(col):
x=col[0]
y=col[1]
z=col[2]
return x+y+z
df.apply(avg_3_apply)
🔹 数据统计与分析
1、基本计算
pandas会根据index
自动匹配计算,无数据会使用NAN
来表示
2、统计
统计函数汇总:
函数 | 描述 |
---|---|
count | 非空值的计数(不包含NAN) |
size | 计数(包含空值) |
sum | 值的总和 |
mean | 平均值 |
min | 最低限度 |
max | 最大 |
abs | 绝对值 |
std | 标准差 |
cusum | 累加求和 |
>>> df.mean() # 平均值计算,可以指定axis,跟numpy差不多 # 默认按列计算
如果想用其他库或者自己的统计函数,可以使用df/series.aggregate(func)
(agg()
等于aggregate()
)来使用统计函数。对于aggregate()的扩展用法,我会在后期写一篇文章叙述。
3、分组统计
使用df.groupby()
函数
df.groupby('year')['列'].mean()
按圆括号里的列的值分组,用方括号里面的列的数值计算平均值。
4、数据分析
df.corr() # 属性相关性分析,两两分析,1表示相关性强。
pd.plotting.scatter_matrix(df) # 属性相关性图表化分析。图形化,容易看
🔹 合并、连接
1、concat()
这里的连接主要指首尾连接,连接的两个dataframe
对象的列名最好一致,才能首尾连接;如果不一致,缺的地方会填充NAN。
使用conta()
函数连接
>>> df1
col1 col2
0 1 3
1 2 4
>>> df2
col1 col2
0 2 4
1 7 8
>>> df_concat=pd.concat([df1,df2])
>>> df_concat
col1 col2
0 1 3
1 2 4
0 2 4
1 7 8
concat()常用参数
参数 | 描述 |
---|---|
axis: {0, 1, …} | 默认 0。要连接的轴。0为列方向连接 |
join: {‘inner’, ‘outer’} | 默认为’outer’。如何处理其他轴上的索引。外部用于联合(求并集),内部用于交叉(求交集)。 |
ignore_index:bool | 默认为 False。如果为 True,则不要使用连接轴上的索引值。结果轴将标记为 0, …, n - 1。如果您要连接对象,而连接轴没有有意义的索引信息,这将非常有用。 |
2、merge()
merge()
有所有标准数据库连接操作
pd.merge(
left,
right,
how="inner",
on=None,
left_on=None,
right_on=None,
left_index=False,
right_index=False,
sort=True,
suffixes=("_x", "_y"),
copy=True,
indicator=False,
validate=None,
)
参数 | 解释 |
---|---|
how | 定义合并方式,选择参数有 『inner』,『outer』, 『left’』,『right』 |
on | 定义2个 DataFrame 中都必须包含的列用于连接(索引键) |
left_on 和 right_on | 指定要合并的左侧或右侧对象中存在的列或索引 |
left_index 和 right_index | 默认为 False,设置为以索引列作为合并基准 |
suffixes | 字符串元组,用于附加到不是合并键的相同列名 |
🔹 迭代遍历
pandas官方不建议遍历,遍历会影响性能,可以使用索引、pandas内置方法、numpy函数替代。还有就是迭代过程中绝对不要修改值,修改也无效。
1、遍历列名称
# 普通遍历遍历的是列名称
for col in df:
print(col)
2、遍历内容
items()
遍历键值对
注意这种方法是按照列的顺序遍历来的
>>> df
col1 col2
row1 1 3
row2 2 4
>>> for column,row in df.items():
print(column)
print(row)
col1
row1 1
row2 2
Name: col1, dtype: int64
col2
row1 3
row2 4
Name: col2, dtype: int64
iterrows()
按行迭代
>>>for row_index, row in df.iterrows():
print(row_index)
print(row)
row1
col1 1
col2 3
Name: row1, dtype: int64
row2
col1 2
col2 4
Name: row2, dtype: int64
itertuples()
返回行元组
>>> for row in df.itertuples():
print(row)
Pandas(Index='row1', col1=1, col2=3)
Pandas(Index='row2', col1=2, col2=4)
🔹 基本绘图
如果什么参数都不加,会将每列的图像都会展示在一张图上。
df.plot()
可以加上x,y,kind等参数绘制自定义图
df.plot(kind="绘制图的类型",x="列名1",y="列名2",title="",xlabel="",ylabel="",style="")# matplotlib库中的方法同样适用。
kind支持的参数:
‘line’ : 线图(默认)
‘bar’ : 垂直条形图
‘barh’ : 水平条形图
‘hist’ : 直方图
“box”:箱线图
‘kde’:核密度估计图
‘area’ : 面积图
‘pie’:饼图
‘scatter’ :散点图(仅限 DataFrame)
‘hexbin’ : hexbin 图(仅限 DataFrame)