pandas读书笔记 算数运算和数据对齐
pandas最重要的一个功能是,它可以对不同索引的对象进行算数运算。在对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集。
Series
s1=Series([7.3,-25,3.4,1.5],index=['a','c','d','e']) s2=Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g']) s1 Out[6]: a 7.3 c -25.0 d 3.4 e 1.5 dtype: float64 s2 Out[7]: a -2.1 c 3.6 e -1.5 f 4.0 g 3.1 dtype: float64
它们相加就会产生:
s1+s2 Out[8]: a 5.2 c -21.4 d NaN e 0.0 f NaN g NaN dtype: float64
自动的数据对齐操作在不重叠的索引处引入了NA值。
DataFrame
对齐操作会同时发生在行和列上:
df1=DataFrame(np.arange(9).reshape((3,3)),columns=list('bcd'), index=['Ohio','Texas','Colorado']) df2=DataFrame(np.arange(12).reshape((4,3)),columns=list('bde'), index=['Utah','Ohio','Texas','Oregon']) df1 Out[11]: b c d Ohio 0 1 2 Texas 3 4 5 Colorado 6 7 8 df2 Out[12]: b d e Utah 0 1 2 Ohio 3 4 5 Texas 6 7 8 Oregon 9 10 11
把它们相加后会返回一个新的DataFrame,其索引和列为原来那两个DataFrame的并集:
df1+df2 Out[13]: b c d e Colorado NaN NaN NaN NaN Ohio 3.0 NaN 6.0 NaN Oregon NaN NaN NaN NaN Texas 9.0 NaN 12.0 NaN Utah NaN NaN NaN NaN
在算数方法中填充值
在对不同索引的对象进行算数运算时,你可能希望当一个对象中某个轴标签在另一个对象中找不到时填充一个特殊值:
df1=DataFrame(np.arange(12).reshape((3,4)),columns=list('abcd')) df2=DataFrame(np.arange(20).reshape((4,5)),columns=list('abcde')) df1 Out[16]: a b c d 0 0 1 2 3 1 4 5 6 7 2 8 9 10 11 df2 Out[17]: a b c d e 0 0 1 2 3 4 1 5 6 7 8 9 2 10 11 12 13 14 3 15 16 17 18 19
将它们相加时,没有重叠的位置就会产生NA值:
df1+df2 Out[18]: a b c d e 0 0.0 2.0 4.0 6.0 NaN 1 9.0 11.0 13.0 15.0 NaN 2 18.0 20.0 22.0 24.0 NaN 3 NaN NaN NaN NaN NaN
使用df1的add方法,传入df2以及一个fill_value参数:
df1.add(df2,fill_value=0) Out[19]: a b c d e 0 0.0 2.0 4.0 6.0 4.0 1 9.0 11.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
与此类似,在对Series或DataFrame重新索引时,也可以指定一个填充值:
df1.reindex(columns=df2.columns,fill_value=0) Out[20]: a b c d e 0 0 1 2 3 0 1 4 5 6 7 0 2 8 9 10 11 0
灵活的算数方法
add ->用于加法(+)的方法
sub ->用于减法(-)的方法
div ->用于除法(/)的方法
mul ->用于乘法(*)的方法
DataFrame和Series之间的运算
arr=np.arange(12).reshape((3,4)) arr Out[22]: array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) arr[0] Out[23]: array([0, 1, 2, 3]) arr-arr[0] Out[24]: array([[0, 0, 0, 0], [4, 4, 4, 4], [8, 8, 8, 8]])
这就叫做广播(broadcasting)。DataFrame和Series之间的运算差不多如此:
frame=DataFrame(np.arange(12).reshape((4,3)),columns=list('bde'), index=['Utah','Ohio','Texas','Oregon']) series=frame.ix[0] __main__:1: DeprecationWarning: .ix is deprecated. Please use .loc for label based indexing or .iloc for positional indexing See the documentation here: http://pandas.pydata.org/pandas-docs/stable/indexing.html#ix-indexer-is-deprecated frame Out[27]: b d e Utah 0 1 2 Ohio 3 4 5 Texas 6 7 8 Oregon 9 10 11 series Out[28]: b 0 d 1 e 2 Name: Utah, dtype: int32
匹配列,沿行进行广播
默认情况下,DataFrame和Series之间的算数运算会将Series的索引匹配到DataFrame的列,然后沿着行一直向下广播。
frame-series Out[29]: b d e Utah 0 0 0 Ohio 3 3 3 Texas 6 6 6 Oregon 9 9 9
也可以理解为纵向广播↓。
如果某个索引值在DataFrame的列或Series的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集:
series2=Series(range(3),index=['b','e','f']) frame+series2 Out[31]: 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
匹配行在列上广播
则必须使用算数运算方法:
series3=frame['d'] frame Out[34]: b d e Utah 0 1 2 Ohio 3 4 5 Texas 6 7 8 Oregon 9 10 11 series3 Out[35]: Utah 1 Ohio 4 Texas 7 Oregon 10 Name: d, dtype: int32 frame.sub(series3,axis=0) Out[36]: b d e Utah -1 0 1 Ohio -1 0 1 Texas -1 0 1 Oregon -1 0 1
传入的轴号就是希望匹配的轴。
可以理解为横向广播 →