pandas 笔记006
六、pandas函数应用
import numpy as np
import pandas as pd
1. apply 和 applymap
1.1 可以直接使用numpy的函数
df1 = pd.DataFrame(np.random.randn(5,4)) # np.random.randn:生成均值(μ)为0,标准差(σ)为1的标准正态分布的值。
df1
0 1 2 3
0 0.459249 1.133382 -0.744435 1.039885
1 -1.361926 -1.142337 -0.637301 -0.628044
2 -1.640772 -0.022080 0.739055 0.311488
3 0.264304 1.719474 0.355358 0.607512
4 0.046507 -0.538629 -0.058423 -0.829712
向上取整ceil()
np.ceil(df1)
0 1 2 3
0 1.0 2.0 -0.0 2.0
1 -1.0 -1.0 -0.0 -0.0
2 -1.0 -0.0 1.0 1.0
3 1.0 2.0 1.0 1.0
4 1.0 -0.0 -0.0 -0.0
绝对值函数abs()
:
np.abs(df1) #绝对值函数
0 1 2 3
0 0.459249 1.133382 0.744435 1.039885
1 1.361926 1.142337 0.637301 0.628044
2 1.640772 0.022080 0.739055 0.311488
3 0.264304 1.719474 0.355358 0.607512
4 0.046507 0.538629 0.058423 0.829712
更多numpy函数可以看这里>>>numpy函数
1.2 通过apply将函数应用到列或行
df2 = pd.DataFrame(np.random.randn(5,4))
print(df2)
print("="*50)
print(df2.max(axis=1)) #求每行最大值,默认是axis=0求每列最大值
0 1 2 3
0 0.682475 0.525799 1.484901 -0.503572
1 1.202740 0.389814 0.346540 -1.820890
2 -0.371480 -0.456603 0.200057 0.225045
3 -0.294340 -0.563729 -0.371371 -0.844397
4 0.277183 1.241754 1.620518 0.866249
==================================================
0 1.484901
1 1.202740
2 0.225045
3 -0.294340
4 1.620518
dtype: float64
lambda
是一个匿名函数,省略了函数的定义,冒号左边是参数(可有多个),右边是返回值的表达式。
#使用apply函数
a = lambda x:x.max() # 默认是axis=0,求列的最大值
df2.apply(a)
0 1.202740
1 1.241754
2 1.620518
3 0.866249
dtype: float64
通过apply()函数指定axis=1
,求每行最大值
b = lambda x:x.max() #默认是axis=0 列
df2.apply(b,axis=1) # 指定axis=1,行
0 1.484901
1 1.202740
2 0.225045
3 -0.294340
4 1.620518
dtype: float64
1.3通过applymap将函数应用到每个数据
f1 = pd.DataFrame(np.random.randn(5,4)) #np.random.randn:生成均值(μ)为0,标准差(σ)为1的标准正态分布的值。
f1
0 1 2 3
0 0.200545 0.256181 -0.336579 -0.900013
1 0.261780 0.295117 0.841681 0.522533
2 -0.730609 -0.346353 0.265663 -0.186697
3 0.711057 0.207577 -0.000193 0.490014
4 -0.418289 -0.126728 0.043007 1.053655
保留两位小数
#定义匿名函数x,返回保留两位小数的x
t = lambda x: '%.2f'%x
f1.applymap(t) # 每个数据都保留两位小数(四舍五入)
0 1 2 3
0 0.20 0.26 -0.34 -0.90
1 0.26 0.30 0.84 0.52
2 -0.73 -0.35 0.27 -0.19
3 0.71 0.21 -0.00 0.49
4 -0.42 -0.13 0.04 1.05
2.排序
2.1 按索引排序(sort_index())
2.1.1 Series
a1 = pd.Series(np.arange(4),index=list('bcda'))
a1
b 0
c 1
d 2
a 3
dtype: int32
sort_index()
默认按索引升序排序(ascending=True
)
a1.sort_index() #默认按索引升序排序(ascending=True)
a 3
b 0
c 1
d 2
dtype: int32
按索引降序排序 ascending=False
a1.sort_index(ascending=False) #降序排序
d 2
c 1
b 0
a 3
dtype: int32
2.1.2 DataFrame
a2 = pd.DataFrame(np.arange(12).reshape(3,4),index=list('adb'),columns=list('BDAC'))
a2
B D A C
a 0 1 2 3
d 4 5 6 7
b 8 9 10 11
按行排序,默认axis=0,行索引值升序排序
#按行排序,默认axis=0
a2.sort_index()
B D A C
a 0 1 2 3
b 8 9 10 11
d 4 5 6 7
按列排序,默认axis=0,列索引值升序排序
print(a2.sort_index(axis=1)) # 默认升序
print("="*30)
print(a2.sort_index(axis=1,ascending=False)) #降序
A B C D
a 2 0 3 1
d 6 4 7 5
b 10 8 11 9
==============================
D C B A
a 1 3 0 2
d 5 7 4 6
b 9 11 8 10
2.2 按值排序(sort_values())
2.2.1 Series
a3 = pd.Series([1,5,np.nan,7,2],index=list('abcde'))
a3
a 1.0
b 5.0
c NaN
d 7.0
e 2.0
dtype: float64
默认升序 ,当有空值NAN值时,默认将NAN值排在最后。
a3.sort_values() #默认升序 ,当有空值NAN时,默认将NAN排在最后
a 1.0
e 2.0
b 5.0
d 7.0
c NaN
dtype: float64
指定降序,当有空值NAN时,默认将NAN排在最后。
a3.sort_values(ascending=False) #降序,当有空值NAN时,默认将NAN排在最后
d 7.0
b 5.0
e 2.0
a 1.0
c NaN
dtype: float64
2.2.2 DataFrame
a4 = pd.DataFrame({'a':[8,5,0,4],'b':[4,1,5,2],'c':[7,2,4,1]},index=list('CDBA'))
a4
a b c
C 8 4 7
D 5 1 2
B 0 5 4
A 4 2 1
指定对a列(元素所在整行会该变)进行排序(默认升序)。
a4.sort_values(by='a')
a b c
B 0 5 4
A 4 2 1
D 5 1 2
C 8 4 7
指定降序(元素所在整行会变)。
a4.sort_values(by='a',ascending=False) #降序(元素所在整行会变)
a b c
C 8 4 7
D 5 1 2
A 4 2 1
B 0 5 4
指定多列进行排序时,如果指定的第一列没有相同值则只需按照指定的第一列进行排序即可,如果有相同值,那么这些相同值再根据指定第二列进行排序,如果还有相同值,再根据指定的第三个列进行排序,以此类推。默认升序,元素所在整行会改变。
下面用的是a4这个DataFrame索引,其b列中没有相同元素,所有只需根据b列排序即可。
a4.sort_values(by=['b','a'])
a b c
D 5 1 2
A 4 2 1
C 8 4 7
B 0 5 4
指定降序(元素所在整行会变)
a4.sort_values(by=['b','a'],ascending=False) #降序(元素所在整行会变)
a b c
B 0 5 4
C 8 4 7
A 4 2 1
D 5 1 2
下面的a5中的b列有两个相同的值,这两个值的排列顺序看a列排序。
a5 = pd.DataFrame({'a':[8,5,0,4],'b':[4,1,5,4],'c':[7,2,4,1]},index=list('CDBA'))
print(a5)
print("="*20)
print(a5.sort_values(by=['b','a'])) # 默认升序
print("="*20)
print(a5.sort_values(by=['b','a'],ascending=False)) # 指定降序
a b c
C 8 4 7
D 5 1 2
B 0 5 4
A 4 4 1
====================
a b c
D 5 1 2
A 4 4 1
C 8 4 7
B 0 5 4
====================
a b c
B 0 5 4
C 8 4 7
A 4 4 1
D 5 1 2
3.唯一值和成员属性
3.1 unique()
b = pd.Series([2,4,7,8,4,5,7,np.nan,4],index=['a','a','a','a','a','c','c','c','c'])
b
a 2.0
a 4.0
a 7.0
a 8.0
a 4.0
c 5.0
c 7.0
c NaN
c 4.0
dtype: float64
返回出现过的数(数组类型),有缺失值返回nan
b1 = b1.unique() #返回出现过的数(数组类型),有缺失值也会返回nan
b1
array([ 2., 4., 7., 8., 5., nan])
索引值不是唯一的,可以相同
b2.index.is_unique
False
3.2 value_counts()
b3 = pd.Series([2,4,7,8,4,5,7,np.nan,4])
b3
0 2.0
1 4.0
2 7.0
3 8.0
4 4.0
5 5.0
6 7.0
7 NaN
8 4.0
dtype: float64
返回一个Series索引,左边是出现过的数,右边是出现的次数,nan为空值,不返回
b3.value_counts()
4.0 3
7.0 2
8.0 1
2.0 1
5.0 1
dtype: int64
3.3 isin()
判断值是否存在,将要寻找的值与Series
和DataFrame
里面的每个值进行匹配,返回一个布尔值,如果匹配成功则返回True
,否则返回False
Series
判断一个值是否存在
b3.isin([4])
0 False
1 True
2 False
3 False
4 True
5 False
6 False
7 False
8 True
dtype: bool
判断多个值是否存在
b3.isin([4,8]) #判断多个值是否存在
0 False
1 True
2 False
3 True
4 True
5 False
6 False
7 False
8 True
dtype: bool
DataFrame
b4 = pd.DataFrame({'a':[8,5,0,4],'b':[4,1,5,2],'c':[7,2,4,1]},index=list('CDBA'))
b4
a b c
C 8 4 7
D 5 1 2
B 0 5 4
A 4 2 1
b4.isin([4,2])
a b c
C False True False
D False False True
B False False True
A True True False
4.处理缺失数据
处理缺失数据思路:
-
1.判断是否存在缺失值 isnull()
-
2.丢弃缺失数据 dropna()
-
3.填充缺失数据 fillna()
b1 = pd.DataFrame([np.random.randn(3), [1., 2., np.nan],
[np.nan, 4., np.nan], [1., 2., 3.],[np.nan,np.nan,np.nan]])
b1
0 1 2
0 0.907143 -1.930521 -0.936026
1 1.000000 2.000000 NaN
2 NaN 4.000000 NaN
3 1.000000 2.000000 3.000000
4 NaN NaN NaN
4.1 判断是否存在缺失值 isnull()
b1.isnull() #返回布尔值,为缺失值返回True,否则返回False
0 1 2
0 False False False
1 False False True
2 True False True
3 False False False
4 True True True
4.2 丢弃缺失数据 dropna()
b1.dropna() #默认会丢弃存在nan的整行(axis=0)
0 1 2
0 0.27505 2.666388 -1.282808
3 1.00000 2.000000 3.000000
丢弃存在nan的整列
b1.dropna(axis=1) #丢弃存在nan的整列(这里每列都有NAN,所以返回的是行索引)
0
1
2
3
4
参数how='all'
:
只删除整行都是NAN的行(默认为行axis=0)或整列都是NAN的列(axis=1),并且会改变原DataFrame
索引
b11 = pd.DataFrame([[2.5,6,np.nan], [1., 2., np.nan],
[np.nan, np.nan , np.nan], [1., 2., np.nan],[np.nan,np.nan,np.nan]])
print(b11)
print("="*30)
print(b11.dropna(how="all")) # 删除整行NAN
print("="*30)
print(b11.dropna(how="all",axis=1)) # 删除整列NAN
0 1 2
0 2.5 6.0 NaN
1 1.0 2.0 NaN
2 NaN NaN NaN
3 1.0 2.0 NaN
4 NaN NaN NaN
==============================
0 1 2
0 2.5 6.0 NaN
1 1.0 2.0 NaN
3 1.0 2.0 NaN
==============================
0 1
0 2.5 6.0
1 1.0 2.0
2 NaN NaN
3 1.0 2.0
4 NaN NaN
b2 = pd.DataFrame(np.random.randn(7,3))
b2
0 1 2
0 0.234058 1.636350 -0.761125
1 1.721174 0.139274 -0.918762
2 0.722270 1.349294 -0.011783
3 -0.288692 1.178598 -1.491171
4 0.899841 -1.209080 -1.948781
5 1.692673 0.416204 -0.271325
6 0.814284 -0.035392 -0.360542
b2.iloc[:4,1] = np.nan #iloc位置索引,第一个参数为行,第二个参数为列,这里表示将前四行第二列变为NAN
b2.iloc[:2,2] = np.nan #表示将前2行第3列变为NAN
b2
0 1 2
0 0.234058 NaN NaN
1 1.721174 NaN NaN
2 0.722270 NaN -0.011783
3 -0.288692 NaN -1.491171
4 0.899841 -1.209080 -1.948781
5 1.692673 0.416204 -0.271325
6 0.814284 -0.035392 -0.360542
参数thresh : dropna( thresh = n )
表示一行数据如果剔除nan后这行数据剩余的数据的数量大于或等于n时,就返回这行数据,否则不返回。
b2.dropna(thresh=2) # 第0,1行删除NAN后只剩1个数据,不返回,其他行如果剔除NAN的数据数量大于或等于2,返回整行数据
0 1 2
2 0.722270 NaN -0.011783
3 -0.288692 NaN -1.491171
4 0.899841 -1.209080 -1.948781
5 1.692673 0.416204 -0.271325
6 0.814284 -0.035392 -0.360542
b2.dropna(thresh=3) #剔除NAN后返回数据大于3的这行数据
0 1 2
4 0.899841 -1.209080 -1.948781
5 1.692673 0.416204 -0.271325
6 0.814284 -0.035392 -0.360542
4.3 填充缺失值 fillna()
b2 #改变后的b2值如下
0 1 2
0 0.234058 NaN NaN
1 1.721174 NaN NaN
2 0.722270 NaN -0.011783
3 -0.288692 NaN -1.491171
4 0.899841 -1.209080 -1.948781
5 1.692673 0.416204 -0.271325
6 0.814284 -0.035392 -0.360542
填充NAN值为10
b2.fillna(10) #注意填充的数据类型不需要和原有数据类型一致
0 1 2
0 0.234058 10.000000 10.000000
1 1.721174 10.000000 10.000000
2 0.722270 10.000000 -0.011783
3 -0.288692 10.000000 -1.491171
4 0.899841 -1.209080 -1.948781
5 1.692673 0.416204 -0.271325
6 0.814284 -0.035392 -0.360542
4.3.1 精确填充
使用字典
返回一个新的DataFrame对象,不会改变原来的b2,默认参数inplace=False
,如果inplace=True
就会改变原b2
b2.fillna({1:6,2:5}) #表示索引为1的列的nan替换为6,索引为2的nan替换为5,默认参数inplace=False
0 1 2
0 0.234058 6.000000 5.000000
1 1.721174 6.000000 5.000000
2 0.722270 6.000000 -0.011783
3 -0.288692 6.000000 -1.491171
4 0.899841 -1.209080 -1.948781
5 1.692673 0.416204 -0.271325
6 0.814284 -0.035392 -0.360542
4.3.2 参数inplace=True
b2.fillna({1:6,2:5},inplace=True) #inplace=True不返回新的对象,会改变原b2
b2
0 1 2
0 0.234058 6.000000 5.000000
1 1.721174 6.000000 5.000000
2 0.722270 6.000000 -0.011783
3 -0.288692 6.000000 -1.491171
4 0.899841 -1.209080 -1.948781
5 1.692673 0.416204 -0.271325
6 0.814284 -0.035392 -0.360542
4.3.3 参数method=‘ffill’
将每一列第一个NAN的同一列上一行的数填充到该列的NAN中。如果该列全为NAN则不会变化。
q1 = pd.DataFrame(np.random.randn(6,3))
q1.iloc[3:,0] = np.nan
q1.iloc[4:,2] = np.nan
q1
0 1 2
0 -0.877885 0.551821 -2.350924
1 1.812377 -0.106464 -0.135449
2 1.905657 -1.854603 0.477252
3 NaN -0.193901 0.350264
4 NaN -0.766737 NaN
5 NaN 1.163864 NaN
将NAN值填充为其同一列上一行的数1.905657,0.350264
q1.fillna(method='ffill') #返回新对象,不改变q1
0 1 2
0 -0.877885 0.551821 -2.350924
1 1.812377 -0.106464 -0.135449
2 1.905657 -1.854603 0.477252
3 1.905657 -0.193901 0.350264
4 1.905657 -0.766737 0.350264
5 1.905657 1.163864 0.350264
4.3.4 参数limit
表示要限制每列填充NAN的个数.
limit=2
限制最多填两个,第5行的NAN 为第0列的第三个NAN,被限制填充。
q1.fillna(method='ffill',limit=2)
0 1 2
0 -0.877885 0.551821 -2.350924
1 1.812377 -0.106464 -0.135449
2 1.905657 -1.854603 0.477252
3 1.905657 -0.193901 0.350264
4 1.905657 -0.766737 0.350264
5 NaN 1.163864 0.350264