写在前面
虽然用了pandas很长时间了,但是基本也是围绕在用pandas去做一些文件操作以及一些常用功能,每次在用到对DataFrame进行索引时都习惯了数组的 [] 索引方式,所以在使用DataFrame索引时,我都比较习惯于将DataFrame先转换为二维数组,然后以数组的方式进行索引,因为对DataFrame用 [] 进行索引时经常会有一些易错点,而用loc、iloc时,老是忘记它们的适用范围,所以感觉有必要整理一下它们的用法和关系了。
准备
下面还是以之前的数据来进行各种索引方式的演示:
df = pd.read_csv('./data.csv')
print(df)
Name Gender Age Score id
0 Alen Male 18 80 id0
1 Bob Male 19 90 id1
2 Cidy Female 18 93 id2
3 Daniel Male 20 87 id3
4 Ellen Female 17 96 id4
5 Frankie Male 21 100 id5
6 Gate Male 20 88 id6
7 Hebe Female 22 98 id7
loc
loc是通过行(列)标签索引行(列)数据
由于是按照行/列标签进行索引数据,所以这里我们先设置行数据的索引标签:
df = df.set_index('id')
print(df)
Name Gender Age Score
id
id0 Alen Male 18 80
id1 Bob Male 19 90
id2 Cidy Female 18 93
id3 Daniel Male 20 87
id4 Ellen Female 17 96
id5 Frankie Male 21 100
id6 Gate Male 20 88
id7 Hebe Female 22 98
下面按照行列标签进行索引:
像下面的按照单行索引,切片索引都是没有问题的,区别只是在于返回的结果是Series
、DataFrame
或者是其他对象。
print(df.loc['id0']) # return NoneType Object
print(df.loc['id0', 'Name']) # return str
print(df.loc['id0':'id4']) # return DataFrame Object
print(df.loc['id0':'id4', ['Name', 'Age', 'Score']]) # return DataFrame Object
print(df.loc[:, 'Name']) # return Series Object
Name Alen
Gender Male
Age 18
Score 80
Name: id0, dtype: object
Alen
Name Gender Age Score
id
id0 Alen Male 18 80
id1 Bob Male 19 90
id2 Cidy Female 18 93
id3 Daniel Male 20 87
id4 Ellen Female 17 96
Name Age Score
id
id0 Alen 18 80
id1 Bob 19 90
id2 Cidy 18 93
id3 Daniel 20 87
id4 Ellen 17 96
id
id0 Alen
id1 Bob
id2 Cidy
id3 Daniel
id4 Ellen
id5 Frankie
id6 Gate
id7 Hebe
Name: Name, dtype: object
但是如果按照下面的方式索引,则都会报错:
print(df.loc[0])
print(df.loc[0, 0])
print(df.loc[0:4, 0])
print(df.loc[0:4, 0:2])
Error
iloc
iloc是按照行(列)号进行索引行(列)数据
当没有设置行索引的标签时:
df = pd.read_csv('./data.csv')
print(df)
Name Gender Age Score id
0 Alen Male 18 80 id0
1 Bob Male 19 90 id1
2 Cidy Female 18 93 id2
3 Daniel Male 20 87 id3
4 Ellen Female 17 96 id4
5 Frankie Male 21 100 id5
6 Gate Male 20 88 id6
7 Hebe Female 22 98 id7
此时再通过上面报错的行号和列号方式进行索引数据时就不会出错了:
print(df.iloc[0])
print(df.iloc[0, 0])
print(df.iloc[0:4, 1])
print(df.iloc[0:4, 0:2])
Name Alen
Gender Male
Age 18
Score 80
id id0
Name: 0, dtype: object
Alen
0 Male
1 Male
2 Female
3 Male
Name: Gender, dtype: object
Name Gender
0 Alen Male
1 Bob Male
2 Cidy Female
3 Daniel Male
ix
ix是loc和iloc两者的结合,但是官方为了让loc和iloc各尽其职,所以即将废弃ix,所以这里也不建议使用ix。.ix is deprecated. Please use.loc for label based indexing or .iloc for positional indexing
其他索引方式
其他的索引方式就是按照我之前的习惯,将DataFrame转换为一个numpy二维数组,然后通过数组的方式进行索引。
arr = df.values
# mat = df.as_matrix()
print(arr[0])
print(arr[0:4, 2:4])
['Alen' 'Male' 18 80 'id0']
[[18 80]
[19 90]
[18 93]
[20 87]]
其中df.as_matrix()
已经废弃,取而代之的是df.values
。
总结
对于DataFrame进行索引,建议的方式还是采用iloc和loc,因为得到的DataFrame或者Series对象其中有很多内置函数,便于数据分析。
区分两者的关系时,可以根据行是否有标签索引,如果有例如ID、时间之类的标签就用loc,如果没有指定行标签,那就用iloc。
记忆的时候可以这样辅助记忆,行没有标签时,那就给它加上一个标签iloc(index+loc)。