前段時間看Think Python里面有句話記憶猶新,大概意思是:有時候Python讓我們感到困惑,是因為實現(xiàn)一個效果的方法太多,而不是太少。
確實如此,Pandas的DataFrame數(shù)據(jù)選取就存在這樣的問題。本來理解列表索引(了解列表索引請參考:一張圖弄懂python索引和切片)就已經(jīng)很困難了,DataFrame還帶這么多方法。
廢話少說,直接上結(jié)果。
1、loc:通過標(biāo)簽選取數(shù)據(jù),即通過index和columns的值進行選取。loc方法有兩個參數(shù),按順序控制行列選取。
#示例數(shù)據(jù)集
df=pd.DataFrame(np.arange(12).reshape(4,3),columns=list('abc'),index=list('defg'))
df
Out[189]:
a b c
d 0 1 2
e 3 4 5
f 6 7 8
g 9 10 11
#直接索引行
df.loc['d']
Out[190]:
a 0
b 1
c 2
Name: d, dtype: int32
#索引多行
df.loc[['d','e']]
Out[191]:
a b c
d 0 1 2
e 3 4 5
#索引多列
df.loc[:,:'b']
Out[193]:
a b
d 0 1
e 3 4
f 6 7
g 9 10
#如果索引的標(biāo)簽不在index或columns范圍則會報錯,a標(biāo)簽在列中,loc的第一個參數(shù)為行索引。
df.loc['a']
Traceback (most recent call last):
……
KeyError: 'the label [a] is not in the [index]'
2、iloc:通過行號選取數(shù)據(jù),即通過數(shù)據(jù)所在的自然行列數(shù)為選取數(shù)據(jù)。iloc方法也有兩個參數(shù),按順序控制行列選取。
注意:行號和索引有所差異,進行篩選后的數(shù)據(jù)行號會根據(jù)新的DataFrame變化,而索引不會發(fā)生變化。
df
Out[196]:
a b c
d 0 1 2
e 3 4 5
f 6 7 8
g 9 10 11
#選取一行
df.iloc[0]
Out[197]:
a 0
b 1
c 2
Name: d, dtype: int32
#選取多行
df.iloc[0:2]
Out[198]:
a b c
d 0 1 2
e 3 4 5
#選取一列或多列
df.iloc[:,2:3]
Out[199]:
c
d 2
e 5
f 8
g 11
3、ix:混合索引,同時通過標(biāo)簽和行號選取數(shù)據(jù)。ix方法也有兩個參數(shù),按順序控制行列選取。
注意:ix的兩個參數(shù)中,每個參數(shù)在索引時必須保持只使用標(biāo)簽或行號進行數(shù)據(jù)選取,否則會返回一部分控制結(jié)果。
df
Out[200]:
a b c
d 0 1 2
e 3 4 5
f 6 7 8
g 9 10 11
#選取一行
df.ix[1]
Out[201]:
a 3
b 4
c 5
Name: e, dtype: int32
#錯誤的混合索引(想選取第一行和e行)
df.ix[[0,'e']]
Out[202]:
a b c
0 NaN NaN NaN
e 3.0 4.0 5.0
#選取區(qū)域(e行的前兩列)
df.ix['e':,:2]
Out[203]:
a b
e 3 4
f 6 7
g 9 10
4、at/iat:通過標(biāo)簽或行號獲取某個數(shù)值的具體位置。
df
Out[204]:
a b c
d 0 1 2
e 3 4 5
f 6 7 8
g 9 10 11
#獲取第2行,第3列位置的數(shù)據(jù)
df.iat[1,2]
Out[205]: 5
#獲取f行,a列位置的數(shù)據(jù)
df.at['f','a']
Out[206]: 6
5、直接索引 df[]
df
Out[208]:
a b c
d 0 1 2
e 3 4 5
f 6 7 8
g 9 10 11
#選取行
df[0:3]
Out[209]:
a b c
d 0 1 2
e 3 4 5
f 6 7 8
#選取列
df['a']
Out[210]:
d 0
e 3
f 6
g 9
Name: a, dtype: int32
#選取多列
df[['a','c']]
Out[211]:
a c
d 0 2
e 3 5
f 6 8
g 9 11
#行號和區(qū)間索引只能用于行(預(yù)想選取C列的數(shù)據(jù),
#但這里選取除了df的所有數(shù)據(jù),區(qū)間索引只能用于行,
#因defg均>c,所以所有行均被選取出來)
df['c':]
Out[212]:
a b c
d 0 1 2
e 3 4 5
f 6 7 8
g 9 10 11
df['f':]
Out[213]:
a b c
f 6 7 8
g 9 10 11
#df.選取列
df.a
Out[214]:
d 0
e 3
f 6
g 9
Name: a, dtype: int32
#不能使用df.選擇行
df.f
Traceback (most recent call last):
File "<ipython-input-215-6438703abe20>", line 1, in <module>
df.f
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\generic.py", line 2744, in __getattr__
return object.__getattribute__(self, name)
AttributeError: 'DataFrame' object has no attribute 'f'
6、總結(jié)
1).loc,.iloc,.ix,只加第一個參數(shù)如.loc([1,2]),.iloc([2:3]),.ix[2]…則進行的是行選擇
2).loc,.at,選列是只能是列名,不能是position
3).iloc,.iat,選列是只能是position,不能是列名
4)df[]只能進行行選擇,或列選擇,不能同時進行列選擇,列選擇只能是列名。行號和區(qū)間選擇只能進行行選擇。當(dāng)index和columns標(biāo)簽值存在重復(fù)時,通過標(biāo)簽選擇會優(yōu)先返回行數(shù)據(jù)。df.只能進行列選擇,不能進行行選擇。