Bootstrap

科学计算python库:pandas基本使用

🔹 前言

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()函数


🔹 索引/筛选

pandas 查询筛选数据

在这里插入图片描述

选择列

使用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()函数,可以使用表达式来选择。
表达式支持逻辑运算符以外,还支持innot 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)

;