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
但是,如果要進行插值,就必須指定參數。