Pandas 基础 (3)—— 重新索引
1. 重新索引
Pandas 對象的一個重要方法是 reindex,其作用是創建一個適應新索引的新對象。
In [1]: from pandas import Series, DataFrameIn [2]: import pandas as pdIn [3]: obj = Series([1,2,3,4],index=['d','c','b','a'])In [4]: objOut[4]: d 1c 2b 3a 4dtype: int64
調用該 Series 的 reindex 將會根據新索引進行重排。如果某個索引值當前不存在,就引入缺失值。
obj2 = obj.reindex(['a','b','c','d','e'])obj2Out[8]: a 4.0b 3.0c 2.0d 1.0e NaNdtype: float64obj2 = obj.reindex(['a','b','c','d','e'],fill_value=0)obj2Out[10]: a 4b 3c 2d 1e 0dtype: int64
對于時間序列這樣的有序數據,重新索引時可能需要做一些插值處理,,method 選項即可達到此目的。
In [11]: obj3 = Series(['beijing','shanghai','guangzhou'],index=[0,2,4])In [12]: obj3.reindex(range(6),method='ffill')Out[12]: 0 beijing1 beijing2 shanghai3 shanghai4 guangzhou5 guangzhoudtype: object
reindex 的插值 method 選項說明:
-
ffill 或 pad :前向填充(或搬運)值
-
bfill 或 backfill:后向填充(或搬運)值
?
對于 DataFrame, reindex 可以修改行索引、列、或者兩個都修改,如果僅傳入一個序列,則會重新索引行:
In [14]: frame = DataFrame(np.arange(9).reshape((3,3)),index=['a','c','d'],...: columns=['xian','beijing','chongqing'])In [15]: frameOut[15]: xian beijing chongqinga 0 1 2c 3 4 5d 6 7 8In [16]: frame2 = frame.reindex(['a','b','c','d'])In [17]: frame2Out[17]: xian beijing chongqinga 0.0 1.0 2.0b NaN NaN NaNc 3.0 4.0 5.0d 6.0 7.0 8.0In [20]: city = ['xian','beijing','shenzhen']# 使用 columns 關鍵字即可重新索引列In [21]: frame.reindex(columns=city)Out[21]: xian beijing shenzhena 0 1 NaNc 3 4 NaNd 6 7 NaN
也可以同時對行和列進行重新索引,而插值則只能按行應用(即軸0)
In [25]: frameOut[25]: xian beijing chongqinga 0 1 2c 3 4 5d 6 7 8In [26]: frame.reindex(index=['a','b','c','d'],method='ffill').reindex(columns=city)Out[26]: xian beijing shenzhena 0 1 NaNb 0 1 NaNc 3 4 NaNd 6 7 NaN
利用 ix 的標簽索引功能,重新索引任務可以更加簡潔:
In [27]: frame.ix[['a','b','c','d'],city]Out[27]: xian beijing shenzhena 0.0 1.0 NaNb NaN NaN NaNc 3.0 4.0 NaNd 6.0 7.0 NaN
?
2. 丟棄指定軸上的項
2.1 Series
使用 drop 方法,該方法返回的是一個在指定軸上刪除了指定值的新對象
In [28]: obj = Series(np.arange(5),index=['a','b','c','d','e'])In [29]: new_obj = obj.drop('c')In [30]: new_objOut[30]: a 0b 1d 3e 4dtype: int32In [31]: obj.drop(['d','c'])Out[31]: a 0b 1e 4dtype: int32In [32]: objOut[32]: a 0b 1c 2d 3e 4dtype: int32
2.2 DataFrame
對于 DataFrame,可以刪除任意軸上的索引值
In [33]: data = DataFrame(np.arange(16).reshape((4,4)),...: index=['xian','shenzhen','guangzhou','wuhan'],...: columns=['a','b','c','d'])In [34]: dataOut[34]: a b c dxian 0 1 2 3shenzhen 4 5 6 7guangzhou 8 9 10 11wuhan 12 13 14 15In [35]: data.drop(['xian','shenzhen'])Out[35]: a b c dguangzhou 8 9 10 11wuhan 12 13 14 15# axis 默認為0 代表 index,如果要刪除列,則 axis 必須為 1In [36]: data.drop('b',axis=1)Out[36]: a c dxian 0 2 3shenzhen 4 6 7guangzhou 8 10 11wuhan 12 14 15In [37]: data.drop(['c','d'],axis=1)Out[37]: a bxian 0 1shenzhen 4 5guangzhou 8 9wuhan 12 13
?
2.3 索引、選取和過濾
-
Series
In [42]: obj = Series(np.arange(4),index=['a','b','c','d'])In [43]: obj Out[43]: a 0 b 1 c 2 d 3 dtype: int32In [44]: obj['b'] Out[44]: 1In [45]: obj[1] Out[45]: 1In [46]: obj[2:4] Out[46]: c 2 d 3 dtype: int32In [48]: obj[['b','a','d']] Out[48]: b 1 a 0 d 3 dtype: int32In [49]: obj[[1,3]] Out[49]: b 1 d 3 dtype: int32In [50]: obj[obj<2] Out[50]: a 0 b 1 dtype: int32 # 標簽的切片運算是包含末端的 In [51]: obj['b':'d'] Out[51]: b 1 c 2 d 3 dtype: int32設置的方式:
In [52]: obj['b':'d'] = 100In [53]: obj Out[53]: a 0 b 100 c 100 d 100 dtype: int32?
-
DataFrame
對于 DataFrame 進行索引其實就是獲取一個或多個列:
In [54]: data = DataFrame(np.arange(16).reshape((4,4)),...: index=['xian','shenzhen','guangzhou','wuhan'],...: columns=['a','b','c','d'])In [55]: data Out[55]: a b c d xian 0 1 2 3 shenzhen 4 5 6 7 guangzhou 8 9 10 11 wuhan 12 13 14 15In [56]: data['b'] Out[56]: xian 1 shenzhen 5 guangzhou 9 wuhan 13 Name: b, dtype: int32In [57]: data[['c','d']] Out[57]: c d xian 2 3 shenzhen 6 7 guangzhou 10 11 wuhan 14 15In [59]: data[:2] Out[59]: a b c d xian 0 1 2 3 shenzhen 4 5 6 7In [60]: data[data['c']>5] Out[60]: a b c d shenzhen 4 5 6 7 guangzhou 8 9 10 11 wuhan 12 13 14 15通過布爾型 DataFrame 進行索引
In [61]: data < 5 Out[61]: a b c d xian True True True True shenzhen True False False False guangzhou False False False False wuhan False False False FalseIn [62]: data[data<5] = 0In [63]: data Out[63]: a b c d xian 0 0 0 0 shenzhen 0 5 6 7 guangzhou 8 9 10 11 wuhan 12 13 14 15為了在 DataFrame 的行上進行標簽索引,引入專門的索引字段 ix,可以通過 NumPy 式的標記法以及軸標簽從 DataFrame 選取行和列的子集。
In [65]: data.ix['shenzhen',['b','c']] Out[65]: b 5 c 6 Name: shenzhen, dtype: int32 # [3,0,1] 代表選取 data 的第 3、0、1列 In [67]: data.ix[['shenzhen','wuhan'],[3,0,1]] Out[67]: d a b shenzhen 7 0 5 wuhan 15 12 13In [68]: data.ix[2] Out[68]: a 8 b 9 c 10 d 11 Name: guangzhou, dtype: int32In [69]: data.ix[:'shenzhen','b'] Out[69]: xian 0 shenzhen 5 Name: b, dtype: int32In [70]: data.ix[data.c > 5, :3] Out[70]: a b c shenzhen 0 5 6 guangzhou 8 9 10 wuhan 12 13 14[外鏈圖片轉存失敗(img-4KDuEYER-1562076864605)(pandas-基本功能\DataFrame的索引選項.jpg)]
?
2.4 算術運算和數據對齊
Pandas 最重要的一個功能是,它可以對不同索引的對象進行算術運算。在將對象相加時,如果存在不同的索引對,則結果的索引就是該索引對的并集:
-
Series
In [71]: s1 = Series([1,2,3,4],index=['a','b','c','d'])In [72]: s2 = Series([5,6,7,8],index=['a','b','c','e'])In [73]: s1 Out[73]: a 1 b 2 c 3 d 4 dtype: int64In [74]: s2 Out[74]: a 5 b 6 c 7 e 8 dtype: int64In [75]: s1 + s2 Out[75]: a 6.0 b 8.0 c 10.0 d NaN e NaN dtype: float64?
-
DataFrame
對于 DataFrame ,對齊操作會同時發生在行和列上:
In [76]: df1 = DataFrame(np.arange(9).reshape((3,3)),columns=list('bcd'),...: index=['xian','shenzhen','beijing'])In [77]: df2 = DataFrame(np.arange(12).reshape((4,3)),columns=list('bde'),...: index=['xian','shenzhen','wuhan','hangzhou'])In [78]: df1 Out[78]: b c d xian 0 1 2 shenzhen 3 4 5 beijing 6 7 8In [79]: df2 Out[79]: b d e xian 0 1 2 shenzhen 3 4 5 wuhan 6 7 8 hangzhou 9 10 11In [80]: df1 + df2 Out[80]: b c d e beijing NaN NaN NaN NaN hangzhou NaN NaN NaN NaN shenzhen 6.0 NaN 9.0 NaN wuhan NaN NaN NaN NaN xian 0.0 NaN 3.0 NaN?
2.5 在算術方法中填充值
在對不同索引的對象進行算術運算時,希望當一個對象中某個軸標簽在另外一個對象中找不到時填充一個特殊值:
In [84]: df1 = DataFrame(np.arange(12).reshape((3,4)),columns=list('abcd'))In [85]: df2 = DataFrame(np.arange(20).reshape((4,5)),columns=list('abcde'))In [86]: df1
Out[86]: a b c d
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11In [87]: df2
Out[87]: 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 19In [88]: df1 + df2
Out[88]: 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 [89]: df1.add(df2, fill_value=0)
Out[89]: 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
常用的算術方法
| 方法 | 說明 |
|---|---|
| add | 用于加法(+)的方法 |
| sub | 用于減法(-)的方法 |
| mul | 用于乘法(*)的方法 |
| div | 用于除法(/)的方法 |
?
2.6 DataFrame 和 Series 之間的運算
這個叫做廣播
In [90]: arr = np.arange(12).reshape((3,4))In [91]: arr
Out[91]:
array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]])In [92]: arr - arr[0]
Out[92]:
array([[0, 0, 0, 0],[4, 4, 4, 4],[8, 8, 8, 8]])
In [93]: frame = DataFrame(np.arange(12).reshape((4,3)),columns=list('bde'),...: index=['xian','wuhan','guangzhou','chongqing'])In [93]: In [94]: series = frame.ix[0]In [95]: frame
Out[95]: b d e
xian 0 1 2
wuhan 3 4 5
guangzhou 6 7 8
chongqing 9 10 11In [96]: series
Out[96]:
b 0
d 1
e 2
Name: xian, dtype: int32
默認情況下,DataFrame 和 Series 之間的算術運算會將 Series 的索引匹配到 DataFrame 的列,然后沿著行一直向下廣播:
In [97]: frame - series
Out[97]: b d e
xian 0 0 0
wuhan 3 3 3
guangzhou 6 6 6
chongqing 9 9 9
如果某個索引值在 DataFrame 的列或 Series 的索引中找不到,則參與運算的兩個對象就會被重新索引以形成并集:
In [98]: series2 = Series(range(3), index=['b','e','f'])In [99]: frame + series2
Out[99]: b d e f
xian 0.0 NaN 3.0 NaN
wuhan 3.0 NaN 6.0 NaN
guangzhou 6.0 NaN 9.0 NaN
chongqing 9.0 NaN 12.0 NaN
如果希望匹配行且在列上廣播,則必須使用算術運算方法。
In [101]: series3 = frame['d']In [102]: frame
Out[102]: b d e
xian 0 1 2
wuhan 3 4 5
guangzhou 6 7 8
chongqing 9 10 11In [103]: series3
Out[103]:
xian 1
wuhan 4
guangzhou 7
chongqing 10
Name: d, dtype: int32
# 傳入的軸號就是希望匹配的軸
In [104]: frame.sub(series3, axis=0)
Out[104]: b d e
xian -1 0 1
wuhan -1 0 1
guangzhou -1 0 1
chongqing -1 0 1
?
2.7 函數應用和映射
P148
2.8 排序和排名
要對行或列進行排序(按字典順序),使用 sort_index 方法,它將返回一個已排序的新對象:
In [105]: obj = Series(range(4),index=['d','a','b','c'])In [106]: obj
Out[106]:
d 0
a 1
b 2
c 3
dtype: int64In [107]: obj.sort_index()
Out[107]:
a 1
b 2
c 3
d 0
dtype: int64
對于 DataFrame,則可以根據任意一個軸上的索引進行排序:
In [108]: frame = DataFrame(np.arange(8).reshape((2,4)),index=['three','one'],...: columns=['d','a','b','c'])In [109]: frame
Out[109]: d a b c
three 0 1 2 3
one 4 5 6 7In [110]: frame.sort_index()
Out[110]: d a b c
one 4 5 6 7
three 0 1 2 3In [111]: frame.sort_index(axis=1)
Out[111]: a b c d
three 1 2 3 0
one 5 6 7 4
默認是按升序排序的,也可以降序排序:
In [112]: frame.sort_index(axis=1,ascending=False)
Out[112]: d c b a
three 0 3 2 1
one 4 7 6 5
若要按值對 Series 進行排序,可使用其 sort_values方法:
In [113]: obj = Series(4,7,-3,2)In [116]: obj
Out[116]:
0 4
1 7
2 -3
3 2
dtype: int64In [118]: obj.sort_values()
Out[118]:
2 -3
3 2
0 4
1 7
dtype: int64
在排序時,任何缺失值默認都會被放到 Series 的末尾:
In [119]: obj = Series([4,np.nan,7,np.nan,-3,2])In [120]: obj.sort_values()
Out[120]:
4 -3.0
5 2.0
0 4.0
2 7.0
1 NaN
3 NaN
dtype: float64
在 DataFrame 中,可以根據一個或多個列中的值進行排序,將列名傳遞給 by 關鍵字參數:
In [123]: frame = DataFrame({'b':[4,7,-3,2],'a':[0,1,0,1]})In [124]: frame
Out[124]: a b
0 0 4
1 1 7
2 0 -3
3 1 2In [126]: frame.sort_values(by='b')
Out[126]: a b
2 0 -3
3 1 2
0 0 4
1 1 7
要根據多個列進行排序,傳入名稱的列表即可:
In [127]: frame.sort_values(by=['a','b'])
Out[127]: a b
2 0 -3
0 0 4
3 1 2
1 1 7
默認情況下,rank 是通過 “為各組分配一個平均排名” 的方式破壞平級關系的。
In [128]: obj = Series([7,-5,7,4,2,0,4])In [129]: obj.rank()
Out[129]:
0 6.5
1 1.0
2 6.5
3 4.5
4 3.0
5 2.0
6 4.5
dtype: float64
# 根據值在原數據中出現的順序給出排名
In [130]: obj.rank(method='first')
Out[130]:
0 6.0
1 1.0
2 7.0
3 4.0
4 3.0
5 2.0
6 5.0
dtype: float64
# 降序排名
In [131]: obj.rank(ascending=False,method='max')
Out[131]:
0 2.0
1 7.0
2 2.0
3 4.0
4 5.0
5 6.0
6 4.0
dtype: float64
DataFrame 可以在行或列上計算排名
In [132]: frame = DataFrame({'b':[4,7,-3,2],'a':[0,1,0,1]})In [133]: frame
Out[133]: a b
0 0 4
1 1 7
2 0 -3
3 1 2In [134]: frame.rank(axis=1)
Out[134]: a b
0 1.0 2.0
1 1.0 2.0
2 2.0 1.0
3 1.0 2.0
2.9 帶有重復值的軸索引
對于帶有重復值的索引,如果某個索引對應多個值,則返回一個 Series;而對應單個值的,則返回一個標量值:
In [135]: obj = Series(range(5), index=['a','a','b','b','c'])In [136]: obj
Out[136]:
a 0
a 1
b 2
b 3
c 4
dtype: int64In [137]: obj.index.is_unique
Out[137]: FalseIn [138]: obj['a']
Out[138]:
a 0
a 1
dtype: int64In [139]: obj['c']
Out[139]: 4
對 DataFrame 進行索引時原理同上:
In [140]: df = DataFrame(np.random.randn(4,3),index=['a','a','b','b'])In [141]: df
Out[141]: 0 1 2
a -0.882972 1.028678 -0.867953
a 0.453870 -0.057848 0.671163
b -1.035427 -0.186319 1.917317
b -0.305498 -1.377157 -0.385813In [142]: df.ix['b']
Out[142]: 0 1 2
b -1.035427 -0.186319 1.917317
b -0.305498 -1.377157 -0.385813
?
總結
以上是生活随笔為你收集整理的Pandas 基础 (3)—— 重新索引的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: s6多少钱啊?
- 下一篇: Pandas 基础 (4)—— 汇总和计