开发者学堂课程【高校精品课-华东师范大学 - Python 数据科学基础与实践:Pandas 基础4】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/1067/detail/15384
Pandas 基础4
内容介绍:
一、Arithmetic methods with fill values(带填充值的算术方法)
二、Operations between DataFrame and Series (DataFrame 和 Series 之间的操作)
三、Function Application and Mapping(函数应用和映射)
这个空值有时候显示出来可能不好看,而且不便于以后的数据计算,因为空和别的计算都是空。所以,我们可以用一个初始化的方法把这个空给它填充掉,也就是说,带填充值的一个算术方法,那我们一般的话是把那个空填充成零。
一、Arithmetic methods with fill values(带填充值的算术方法)
对于上面那些缺失值,我们想要填上0:
In [33]: df1 = pd. DataFrame(np. arange(12.).reshape((3,4)),
columns=list('abcd'))
df2 = pd. DataFrame (np.arange(20. ).reshape((4,5)),
columns=list('abcde'))
df2.loc[1, 'b' ] = np.nan
In[72]: df1
out[72]:
a b c d
0 0.0 1.0 2.0 3.0
1 4.0 5.0 6.0 7.0
2 8.0 9.0 10.0 11.0
我们构造两个数据框,然后,我们可以查找一下数据框里面的一个元素,然后给它设成一个值等于空,那么我们来显示一下这个结果。
In[73]: df2
out[73]:
a b c d e
0 0.0 1.0 2.0 3.0 4.0
1 5.0 NaN 7.0 8.0 9.0
2 10.0 11.0 12.0 13.0 14.0
3 15.0 16.0 17.0 18.0 19.0
df2里面有个地方是空的,第一行是0,然后第一列是空,大家看它的空是np里面的一个常数,np.nan是成空,大家注意这里。
不使用add方法的结果:
In[37]: df1 + df2
Out[37]:
a b c d e
0 0.0 2.0 4.0 6.0 NaN
1 9.0 NaN 13.0 15.0 NaN
2 18.0 20.0 22.0 24.0 NaN
3 NaN NaN NaN NaN NaN
两个数据方直接相加,大家注意看看相加以后,就是说,如果没有同样的索引的话,就是行索引列索引的话,它的位置就是空,但是我们可以用这个填充的方法,把空填充成零。
使用fill_value:
In[76]: df1. apld(df2, fill_value=0)
Out[76]:
a b c d e
0 0.0 2.0 4.0 6.0 4.0
1 9.0 5.0 13.0 15.0 9.0
2 18.0 20.0 22.0 24.0 14.0
3 15.0 16.0 17.0 18.0 19.0
来看一下,这里用了add的方法,是df1加上df2,然后fill_value=0,把那些空的值变成零,那么这个空值的地方就变成零了.
思考:
还有哪些算术方法?
每一个都有一个配对的,以r开头,意思是反转:
In [77]: 1 / df1
out[77]:
a b c d
0 inf 1.000000 0.500000 0.333333
1 0.250 0.200000 0.166667 0.142857
2 0.125 0.111111 0.100000 0.090909
求导数,每个元素都可以求导数,第一行是零,因为它是不合法的,所以在第一行是inf,相当于是无限的,那我们也可以用这个函数rdiv相当于是求导数,大家看一下:
In [40]: df1.rdiv(1)
0ut[40]:
a b c d
0 inf 1.000000 0.500000 0.333333
1 0.250 0.200000 0.166667 0.142857
2 0.125 0.111111 0.100000 0.090909
在做重建索引的时候也可以使用fill_value去填充,那么重建索引的话,要给到新的索引名字,那有可能原来没有,那原来没有的话,它是没有按照以前的方法,它应该是空,那可以给它填充成零。
下面我们再来看一下数据框和系列之间的操作,用一单排的例子来帮助一下大家理解一下。
二、Operations between DataFrame and Series (DataFrame 和 Series 之间的操作)
先举个numpy的例子帮助理解,可以考虑成一个二维数组和它的一行:
In[43]:arr = np.arange(12.).reshape((3,4))
Arr
Out[43]: array([[ 0.,1.,2.,3.],
[4,5., 6.,7.],
[ 8.,9.,10.,11.]])
In[81]: arr [0]
out[81]: array([0.,1.,2.,3.])
[82]: arr - arr[0]
out[82]: array([[o., 0.,0.,0.],
[4.,4.,4.,4.],
[8.,8.,8.,8.]])
我们这里有12个数,然后是三行四列,然后,取里面的就是零,因为它里面没有逗号,没有两个元素。如果是逗号的话,左边就是行,右边就是列,而且,里面一个元素的话,那这就代表行,来取第零行。来看一下第零行,然后看看数据框之间的这个计算,数据框和Series之间的计算。数据框我们减掉一个系列,arr[0]就是一个系列,那么arr是一个数据框,数据框减一个系列,那它会在每一行上面进行相减。
来看到结果,结果就是,我们上面这个数据框每一行减去[0.,1.,2.,3.],然后对应元素相减。
可以看到,这个减法用在了每一行上。这种操作叫broadcasting (能理解含义吗? )。
DataFrame和Series的操作也类似:
In [47]: frame = pd.DataFrame(np.arange(12.).reshape((4,3)),
columns=list(' bde'),
index=['Utah', '0hio', 'Texas', 'Oregon'])
series = frame.iloc[0]
In[84]: frame
0ut[84]:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
In[49]: series #index是列名
Out[49]: b 0.0
d 1.0
e 2.0
Name: Utah,dtype: float64
可以理解为series的index与dataframe的列匹配,broadcasting down the rows(向下按行广播);
这里构造数据框,然后找到一个系列,我们显示一下数据框是如上的数据框啊,那么series是如上所示的series,然后就可以进行相减是按广播方式的。
如果一个index既不在DataFrame的column中,也不再series里的index中,那么结果也是合集:
In [87]: series2 = pd.Series(range(3),index=['b', 'e','f'])
frame + series2
out[87]:
b d e f
Utah 0.0 NaN 3.0 NaN
Ohio 3.0 NaN 6.0 NaN
Texas 6.0 NaN 9.0 NaN
oregon 9.0 NaN 12.0 NaN
如果想要广播列,去匹配行,必须要用到算术方法:
In [51]: series3 = frame['d']
Frame
out[52]:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
In[53]: series3 #index是原先index
0ut[53]: Utah 1.0
0hio 4.0
Texas 7.0
0regon 10.0
Name: d,dtype: float64
In[54]: frame.sub(series3, axis='index')
out[54]:
b d e
Utah -1.0 0.0 1.0
ohio -1.0 0.0 1.0
Texas -1.0 0.0 1.0
注意:按照索引series3是一列,所以是在列上进行相减。
axis参数就是用来匹配轴的。在这个例子里是匹配dataframe的row index( axis='index or axis=0),然后再广播。
三、Function Application and Mapping(函数应用和映射)
numpy的ufuncs(element-wise数组方法)也能用在pandas的object上:
In [59]: frame = pd. DataFrame (np.random.randn(4,3),columns=list('bde'),
index=['Utah’, ' 0hio', 'Texas', 'Oregon'])
frame
0ut[62]:
b d e
Utah 1.083190 0.740620 1.297620
Ohio 0.471374 -1.191904 0.885941
Texas 1.064386 0.034862 1.988635
Oregon 0.585409 0.761295 0.071116
In [60]: np.abs(frame)
可以使用np里面的一个函数作用于数据框上面,也就是上面提到的numpy的ufuncs(element-wise数组方法)也能用在pandas的object上。
out[60]:
b d e
Utah 1.083190 0.740620 1.297620
Ohio 0.471374 1.191904 0.885941
Texas 1.064386 0.034862 1.988635
Oregon 0.585409 0.761295 0.071116
另一个常用的操作是把一个用在一维数组上的函数,应用在一行或一列上。要用到DataFrame中的apply函数:
这个函数特别重要,效率也很高。因为apply函数括号里面也是一个函数,所以要先定义一个函数。这个函数是用lambda定义,要注意lambda的使用技巧,lambda后面第一个就是传入的参数,冒号右边的是函数体,代表参数的运算,整体相当于是一个函数。
In [64]: f = lambda x: x.max() - x.min()
frame.apply(f)
Out[64]: b 0.611816
d 1.953198
e 1.917519
dtype: float64
根据上述内容可以看到:索引是bde,是列的意思,等于每一列在它的所有行上进行操作。
这里函数f,计算的是一个series中最大值和最小值的差,在frame中的每一列,这个函数被调用一次。作为结果的series,它的index就是frame的column。
如果你传入axis='column’用于apply,那么函数会被用在每一行:
In [66]: frame.apply(f,axis=' columns')
out[66]: Utah 0.557000
0hio 2.077845
Texas 1.953773
Oregon 0.690178
dtype: float64
像是sum, mean这样的数组统计方法,DataFrame中已经集成了,所以没必要用apply。
apply不会返回标量,只会返回一个含有多个值的series:
如以下例子,返回的是series中的最小值,最大值,索引。
In [67]: def f(x):
return pd.Series ([x.min(,x.max()],index=['min', 'max'])
In[68]: frame
out[68]:
b d e
Utah 1.083190 0.740620 1.297620
Ohio 0.471374 -1.191904 0.885941
Texas 1.064386 0.034862 1.988635
Oregon 0.585409 0.761295 0.071116
out[69]:
b d e
min 0.471374 -1.191904 0.071116
max 1.083190 0.761295 1.988635
这里给的结果是最大值,最小值,有两行数据,之前的最大值最小值只有一行,大家要注意这个差别。