pandas之重新索引
pandas有一个很重要的方法是reindex
,它的作用是创建一个适应新索引的新对象。
对于Series
直接上代码:
import numpy as np
from pandas import Series,DataFrame
ser = Series([-2.4, -1.4, 1.8, 2.8],['z','c','x','d'])
ser
Out[6]:
z -2.4
c -1.4
x 1.8
d 2.8
dtype: float64
ser.reindex(['a','z','x','b','c','d'])
Out[8]:
a NaN
z -2.4
x 1.8
b NaN
c -1.4
d 2.8
dtype: float64
可以观察到,reindex
根据索引进行了重排,并且,如果所以不存在的话就会引入缺失值NaN。
我们可以指定索引所指向的值,使用fill_value参数:
ser.reindex(['a','z','x','b','c','d'],fill_value = 0)
Out[10]:
a 0.0
z -2.4
x 1.8
b 0.0
c -1.4
d 2.8
dtype: float64
而对于一些有序数据,我们有事可能需要进行插值,进而补充确实数据,这样的话,我们可以使用method参数:
ser1 = Series(['Y','P','Z','X'],index = [0, 2, 5, 7])
ser1
Out[12]:
0 Y
2 P
5 Z
7 X
dtype: object
ser1.reindex(range(8),method='ffill')#前向填充
Out[13]:
0 Y
1 Y
2 P
3 P
4 P
5 Z
6 Z
7 X
dtype: object
ser1.reindex(range(8),method='bfill')#后向填充
Out[14]:
0 Y
1 P
2 P
3 Z
4 Z
5 Z
6 X
7 X
dtype: object
可以注意到:
**ffill就是把前面的值向后填充,另外参数pad的作用与其一致。
bfill的作用是把后面的值向前填充,参数backfill的作用与其一致。**
对于DataFrame
reindex
可以修改行和列的索引。如果只传入一个序列,就会重新索引行
不知道,你有没有注意到,在pandas中如果只传入一个序列,或者索引,一般默认是修改行,或者索引行。
frame = DataFrame(np.arange(9).reshape(3,3),index = ['x','y','z'],columns=['BJ','TJ','HEB'])
frame
Out[18]:
BJ TJ HEB
x 0 1 2
y 3 4 5
z 6 7 8
frame1 = frame.reindex(['x','z','s','y'])#重新索引行
frame1
Out[20]:
BJ TJ HEB
x 0.0 1.0 2.0
z 6.0 7.0 8.0
s NaN NaN NaN
y 3.0 4.0 5.0
frame.reindex(columns=['TJ','SJZ','BJ','HEB'])#重新索引列
Out[21]:
TJ SJZ BJ HEB
x 1 NaN 0 2
y 4 NaN 3 5
z 7 NaN 6 8
frame.reindex(index=['a','b','c','d'],method = 'ffill',columns=['BJ','SD','HEB','TJ'])#重新索引列和行,并插值
Out[34]:
BJ SD HEB TJ
a 0 NaN 2 1
b 0 NaN 2 1
c 3 NaN 5 4
d 6 NaN 8 7
可以注意到,进行行列一起索引的时候,行也必须指定参数index,而插值的结果,只会沿着行应用。
但是没有想明白,为什么会出现以下的状况:
frame.reindex(index = ['x','z','s','y'],method = 'ffill',columns=['TJ','SJZ','BJ','HEB'])
Out[23]:
TJ SJZ BJ HEB
x 1.0 NaN 0.0 2.0
z 7.0 NaN 6.0 8.0
s NaN NaN NaN NaN
y 4.0 NaN 3.0 5.0
frame.reindex(index = ['x','z','s','y'],method = 'ffill',columns=['TJ','SJZ','BJ'])
Out[24]:
TJ SJZ BJ
x 1.0 NaN 0.0
z 7.0 NaN 6.0
s NaN NaN NaN
y 4.0 NaN 3.0
frame.reindex(index = ['x','z','s','y'],method = 'ffill')
Out[26]:
BJ TJ HEB
x 0.0 1.0 2.0
z 6.0 7.0 8.0
s NaN NaN NaN
y 3.0 4.0 5.0
frame.reindex(index = ['x','z','s','y'],method = 'bfill')
Out[28]:
BJ TJ HEB
x 0 1 2
z 6 7 8
s 0 1 2
y 3 4 5
求解。
标签ix可以使重新索引变得很简便,不需要指定index和columns参数。
frame.ix[['a','b','c','d'],['BJ','TJ','SD','HEB']]
Out[37]:
BJ TJ SD HEB
a 0.0 1.0 NaN 2.0
b NaN NaN NaN NaN
c 3.0 4.0 NaN 5.0
d 6.0 7.0 NaN 8.0
但是经过试验,好像reindex不指定也可以,
frame.reindex(['a','b','c','d'],['BJ','TJ','SD','HEB'])
Out[35]:
BJ TJ SD HEB
a 0.0 1.0 NaN 2.0
b NaN NaN NaN NaN
c 3.0 4.0 NaN 5.0
d 6.0 7.0 NaN 8.0
但是,如果要进行插值,就必须指定参数。