pandas对象的一个重要反复是reindex,其做用是建立一个适应新索引的新对象。数组
In [136]: obj=Series([4.5,7.2,-5.3,3.6],index=['d','b','a','c']) In [137]: obj2=obj.reindex(['a','b','c','d','e']) In [138]: obj2 Out[138]: a -5.3 b 7.2 c 3.6 d 4.5 e NaN dtype: float64
若是某个索引值不存在,就引入缺失值数据结构
In [140]: obj.reindex(['a','b','c','d','e'],fill_value=0) Out[140]: a -5.3 b 7.2 c 3.6 d 4.5 e 0.0 dtype: float64
对于时间序列这样的有序数据,从新索引时可能须要作一些插值处理,method选项便可达到目的app
In [141]: obj3=Series(['blue','purple','yellow'],index=[0,2,4]) In [142]: obj3.reindex(range(6),method='ffill') Out[142]: 0 blue 1 blue 2 purple 3 purple 4 yellow 5 yellow dtype: object
reindex的(插值) method选项dom
fill或pad:前向填充(或搬运)值ide
bfill或backfill:后向填充(或搬运)值函数
对于DataFrame,reindex能够修改(行)索引、列,或2个都修改,若是只传入一个序列,则从新索引行spa
In [143]: frame=DataFrame(np.arange(9).reshape(3,3),index=['a','b','c'],columns=['one','two','three']) ...: In [144]: frame Out[144]: one two three a 0 1 2 b 3 4 5 c 6 7 8 In [145]: frame2=frame.reindex(['a','b','c','d']) In [146]: frame2 Out[146]: one two three a 0.0 1.0 2.0 b 3.0 4.0 5.0 c 6.0 7.0 8.0 d NaN NaN NaN In [147]: states=['red','yellow','green'] In [148]: frame.reindex(columns=states) Out[148]: red yellow green a NaN NaN NaN b NaN NaN NaN c NaN NaN NaN In [149]: states=['red','one','two'] In [150]: frame.reindex(columns=states) Out[150]: red one two a NaN 0 1 b NaN 3 4 c NaN 6 7
也能够同时对行和列进行从新索引,而插值则只能按行应用code
In [158]: frame.reindex(index=['a','b','c','d'],method='ffill',columns=['one','two','three']) Out[158]: one two three a 0 1 2 b 3 4 5 c 6 7 8 d 6 7 8
利用ix的标签索引功能,从新索引任务能够变得简洁。对象
reindex函数的参数:blog
index:用做索引的新序列。既能够是index实例,也能够是其余序列型的Python数据结构。index会被彻底使用,就像没有任何复制同样。
method:插值(填充)方式
fill_value:在从新索引过程当中,须要填入缺失值时使用的替代值
limit:前向填充或后向填充的最大填充量
level:在MultiIndex的指定级别上匹配简单索引,不然取其子集
copy:默认为true,不管如何都复制,若是为False,则新旧相等就不复制
丢弃某条轴上的一个或多个项很简单,只须要有一个索引数组或列表便可。
In [162]: obj=Series(np.arange(5.),index=['a','b','c','d','e']) In [163]: new_obj=obj.drop('c') In [164]: new_obj Out[164]: a 0.0 b 1.0 d 3.0 e 4.0 dtype: float64 In [165]: obj Out[165]: a 0.0 b 1.0 c 2.0 d 3.0 e 4.0 dtype: float64
对于DataFrame,能够任意删除任意轴上的索引值:
In [166]: data=DataFrame(np.arange(16).reshape(4,4),index=['Ohio','Colorado','Utah','New York'],column ...: s=['one','two','three','four']) In [167]: data.drop(['Colorado','Ohio']) Out[167]: one two three four Utah 8 9 10 11 New York 12 13 14 15
In [170]: data.drop('two',axis=1)
Out[170]:
one three four
Ohio 0 2 3
Colorado 4 6 7
Utah 8 10 11
New York 12 14 15
In [171]: data.drop(['two','four'],axis=1)
Out[171]:
one three
Ohio 0 2
Colorado 4 6
Utah 8 10
New York 12 14
Series索引的工做方式相似于numpy数组的索引,只不过Series的索引值不仅是整数
In [173]: obj=Series(np.arange(4.),index=['a','b','c','d']) In [174]: obj['a'] Out[174]: 0.0 In [175]: obj[1] Out[175]: 1.0 In [176]: obj[['b','a','d']] Out[176]: b 1.0 a 0.0 d 3.0 dtype: float64 In [177]: obj[obj<2] Out[177]: a 0.0 b 1.0 dtype: float64
利用标签的切片运算和普通的Python切片运算不一样,其末端是包含的:
In [180]: obj['b':'c'] Out[180]: b 1.0 c 2.0 dtype: float64
In [181]: obj[2:3]
Out[181]:
c 2.0
dtype: float64
设置的方式也很简单:
In [182]: obj['b':'c']=5 In [183]: obj Out[183]: a 0.0 b 5.0 c 5.0 d 3.0 dtype: float64
DataFrame进行索引就是获取一个或多个列:
In [184]: data Out[184]: one two three four Ohio 0 1 2 3 Colorado 4 5 6 7 Utah 8 9 10 11 New York 12 13 14 15 In [185]: data['one'] Out[185]: Ohio 0 Colorado 4 Utah 8 New York 12 Name: one, dtype: int32
这种索引方式有几个特殊状况。首先经过切片或布尔型数组进行取行:
In [187]: data[:2] Out[187]: one two three four Ohio 0 1 2 3 Colorado 4 5 6 7 In [188]: data[data['three']>5] Out[188]: one two three four Colorado 4 5 6 7 Utah 8 9 10 11 New York 12 13 14 15
另外一种是经过布尔型DataFrame进行索引:
In [189]: data<5 Out[189]: one two three four Ohio True True True True Colorado True False False False Utah False False False False New York False False False False In [190]: data[data<5]=0 In [191]: data Out[191]: one two three four Ohio 0 0 0 0 Colorado 0 5 6 7 Utah 8 9 10 11 New York 12 13 14 15
经过索引字段ix选取行和列的子集:
In [197]: data.ix['Colorado',['two','three']] Out[197]: two 5 three 6 Name: Colorado, dtype: int32
DataFrame的索引选项:
类型:说明
obj[val] : 选取DataFrame的单个列或一组列。在一些特殊状况下会比较便利;布尔型数组、切片、布尔型DataFrame
obj.ix[val]:选取DataFrame的单个行或一组行
obj.ix[:,val]:选取单个列或列子集
obj.ix[val1,val2]:同时选取行和列
reindex方法:将一个或多个轴匹配到新索引
xs方法:根据标签选取单行或单列,并返回一个Series
icol、irow方法:根据整数位置选取单列或单行,并返回一个Series
get_value、set_value方法:根据行标签或列标签选取单个值。
pandas最重要的一个功能是,它能够对不一样索引的对象进行算术运算。在将对象相加时,若是存在不一样的索引对,则结果的索引就是该索引对的并集。
In [7]: s1=Series([7.3,-2.5,3.4,1.5],index=['a','c','d','e']) In [8]: s2=Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g']) In [9]: s1+s2 Out[9]: a 5.2 c 1.1 d NaN e 0.0 f NaN g NaN dtype: float64
自动的数据对齐操做不重叠的索引处引入了NA值。缺失值会在算术运算中传播。
对于DataFrame,对齐操做会同时发生在行和列上:
In [15]: df1=DataFrame(np.arange(9).reshape(3,3),columns=list('bcd'),index=['one','two','three']) In [16]: df2=DataFrame(np.arange(12).reshape(4,3),columns=list('bde'),index=['one','two','three','four']) In [17]: df1+df2 Out[17]: b c d e four NaN NaN NaN NaN one 0.0 NaN 3.0 NaN three 12.0 NaN 15.0 NaN two 6.0 NaN 9.0 NaN
在对不一样的索引对象进行算术运算时,可能但愿当一个对象中某个轴标签在另外一个对象中找不到时,填充一个特殊值:
In [18]: df1=DataFrame(np.arange(12).reshape(3,4),columns=list('abcd')) In [19]: df2=DataFrame(np.arange(20).reshape(4,5),columns=list('abcde')) In [20]: df1+df2 Out[20]: 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参数:
In [21]: df1.add(df2,fill_value=0) Out[21]: 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从新索引时,也能够指定一个填充值:
In [22]: df1.reindex(columns=df2.columns,fill_value=0) Out[22]: 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(乘法)
跟numpy数组同样,DataFrame和Series之间的算术运算也是有明确规定的
In [23]: arr=np.arange(12).reshape(3,4) In [24]: arr Out[24]: array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) In [25]: arr[0] Out[25]: array([0, 1, 2, 3]) In [26]: arr-arr[0] Out[26]: array([[0, 0, 0, 0], [4, 4, 4, 4], [8, 8, 8, 8]])
这就叫广播。DataFrame和Series之间的运算也是如此。
In [27]: frame=DataFrame(np.arange(12).reshape(4,3),columns=list('bde'),index=['one','two','three','four']) In [28]: series=frame.ix[0] In [29]: frame Out[29]: b d e one 0 1 2 two 3 4 5 three 6 7 8 four 9 10 11 In [30]: series Out[30]: b 0 d 1 e 2 Name: one, dtype: int32
默认状况下,DataFrame和Series之间的算术运算会将Series的索引匹配到DataFrame的列,而后沿着行一直向下广播:
In [31]: frame-series Out[31]: b d e one 0 0 0 two 3 3 3 three 6 6 6 four 9 9 9
若是某个索引值在DataFrame的列或Series的索引中找不到,则参与运算的两个对象就会被从新索引以造成并集:
In [32]: series2=Series(range(3),index=['b','e','f']) In [33]: frame+series2 Out[33]: b d e f one 0.0 NaN 3.0 NaN two 3.0 NaN 6.0 NaN three 6.0 NaN 9.0 NaN four 9.0 NaN 12.0 NaN
若是但愿匹配行且在列上广播,那么必须使用算术运算方法:
In [34]: series3=frame['d'] In [35]: frame Out[35]: b d e one 0 1 2 two 3 4 5 three 6 7 8 four 9 10 11 In [36]: series3 Out[36]: one 1 two 4 three 7 four 10 Name: d, dtype: int32 In [37]: frame.sub(series3,axis=0) Out[37]: b d e one -1 0 1 two -1 0 1 three -1 0 1 four -1 0 1
numpy的ufunc(元素级数组方法)也能够用于操做pandas对象
In [40]: frame=DataFrame(np.random.randn(4,3),columns=list('bde'),index=['one','two','three','four']) In [41]: frame Out[41]: b d e one 0.341012 0.864333 0.228682 two -0.838441 0.483385 1.747057 three 0.479806 -2.392724 0.385935 four 0.602425 -0.150350 -0.072265 In [42]: np.abs(frame) Out[42]: b d e one 0.341012 0.864333 0.228682 two 0.838441 0.483385 1.747057 three 0.479806 2.392724 0.385935 four 0.602425 0.150350 0.072265 In [43]: np.sum(frame) Out[43]: b 0.584803 d -1.195355 e 2.289409 dtype: float64
另外一个常见的操做是,将行数应用到各行或各列所造成的一维数组上。DataFrame的apply方法能够实现功能
In [44]: f=lambda x:x.max() - x.min() In [45]: frame.apply(f) Out[45]: b 1.440866 d 3.257057 e 1.819322 dtype: float64 In [46]: frame.apply(f,axis=1) Out[46]: one 0.635651 two 2.585498 three 2.872530 four 0.752775 dtype: float64
许多常见的数组统计功能都被实现成DataFrame的方法,所以无需apply方法。
除了标量值外,传递给apply的函数还能够返回由多个值组成的series:
In [49]: def f(x): ...: return Series([x.min(),x.max()],index=['min','max']) ...: ...: In [50]: frame.apply(f) Out[50]: b d e min -0.838441 -2.392724 -0.072265 max 0.602425 0.864333 1.747057
根据条件对数据集排序也是一种重要的内置运算。要对行或列索引进行排序,可以使用sort_index方法,它返回一个已排序的新对象:
In [51]: obj=Series(range(4),index=list('dabc')) In [52]: obj.sort_index() Out[52]: a 1 b 2 c 3 d 0 dtype: int64
而对于DataFrame,则能够根据任意一个轴上的索引进行排序:
In [54]: frame Out[54]: b d e one 0.341012 0.864333 0.228682 two -0.838441 0.483385 1.747057 three 0.479806 -2.392724 0.385935 four 0.602425 -0.150350 -0.072265 In [55]: frame.sort_index() Out[55]: b d e four 0.602425 -0.150350 -0.072265 one 0.341012 0.864333 0.228682 three 0.479806 -2.392724 0.385935 two -0.838441 0.483385 1.747057 In [56]: frame.sort_index(axis=1) Out[56]: b d e one 0.341012 0.864333 0.228682 two -0.838441 0.483385 1.747057 three 0.479806 -2.392724 0.385935 four 0.602425 -0.150350 -0.072265
数据默认是按升序排序的,也能够按照降序排序:
In [57]: frame.sort_index(axis=1,ascending=False) Out[57]: e d b one 0.228682 0.864333 0.341012 two 1.747057 0.483385 -0.838441 three 0.385935 -2.392724 0.479806 four -0.072265 -0.150350 0.602425
在DataFrame上,若是须要根据一个或多个列中的值进行排序,将一个或多个列的名字传递给by选项便可:
In [71]: frame=DataFrame({'b':[4,7,-2,3],'a':[0,1,0,1]}) In [72]: frame Out[72]: b a 0 4 0 1 7 1 2 -2 0 3 3 1
In [73]: frame.sort_values(by='a')
Out[73]:
b a
0 4 0
2 -2 0
1 7 1
3 3 1
In [77]: frame.sort_index(by=['a','b'])
Out[77]:
b a
2 -2 0
0 4 0
3 3 1
1 7 1
排名跟排序关系密切,且它会增设一个排名值(从1开始,一直到数组中有效数据的数量)。它跟numpy.argsort产生的间接排序索引差很少,只不过它能够根据某种规则破坏平级关系,那就是rank方法。
rank方法是经过”为各组分配一个平均排名“的方式破坏平级关系:
In [78]: obj=Series([7,-5,7,4,2,0,4]) In [79]: obj.rank() Out[79]: 0 6.5 1 1.0 2 6.5 3 4.5 4 3.0 5 2.0 6 4.5 dtype: float64
也能够根据值在源数据中出现的顺序给出排名:
In [80]: obj.rank(method='first') Out[80]: 0 6.0 1 1.0 2 7.0 3 4.0 4 3.0 5 2.0 6 5.0 dtype: float64
也能够按照降序排名:
In [81]: obj.rank(method='max',ascending=False) Out[81]: 0 2.0 1 7.0 2 2.0 3 4.0 4 5.0 5 6.0 6 4.0 dtype: float64
排名用于破坏平级关系的method选项:
average:默认:在相等分组中,为各个值分配平均排名
min:使用整个分组的最小排名
max:使用整个分组最大排名
first:按值在原始数据中出现的顺序分配排名
虽然不少pandas函数都要求标签惟一,但不是强制性的:
In [85]: obj=Series(range(5),index=list('aabbc')) In [86]: obj Out[86]: a 0 a 1 b 2 b 3 c 4 dtype: int64
索引的is_unique属性能够告诉你它的值是否惟一
In [87]: obj.index.is_unique
Out[87]: False
对带有重复值的索引,数据选取的行为将会有些不一样。若是某个索引对应多个值,则返回一个Series,而对应单个值得,则返回一个标量:
In [88]: obj['a'] Out[88]: a 0 a 1 dtype: int64 In [89]: obj['c'] Out[89]: 4
对DataFrame的行进行索引时也是如此:
In [94]: df=DataFrame(np.arange(12).reshape(4,3),index=list('aabb')) In [95]: df.ix['b'] Out[95]: 0 1 2 b 6 7 8 b 9 10 11 In [96]: df Out[96]: 0 1 2 a 0 1 2 a 3 4 5 b 6 7 8 b 9 10 11