Python数据科学手册(四)【Pandas 索引和选择】
前面我们介绍了Numpy的索引和选择操作,Pandas也具有类似的操作,这节我们将介绍Pandas对象的索引和选择操作。
Series数据选择
前面说过,Series有些操作类似一维Numpy数组,有些操作类似Python字典。
将Series看做字典
跟字典类似,Series对象可以根据键获取值:
import pandas as pd
data = pd.Series([0.25, 0.5, 0.75, 1.0],
index=['a', 'b', 'c', 'd'])
data['b']
# 0.5
也可以使用类似字典的表达式或者方法:
'a' in data # True
data.keys() # Index(['a', 'b', 'c', 'd'], dtype='object')
list(data.items()) #[('a', 0.25), ('b', 0.5), ('c', 0.75), ('d', 1.0)]
Series对象也可以像字典一样修改值:
data['e'] = 1.25
将Series看做一维数组
将Series看做一维数组,则可以支持切片等操作:
data['a':'c'] # 显式声明索引进行切片
data[0:2] # 隐式切片
注意上面的索引操作是有区别的,前者包含了最后一个元素,而后者并不包含。
掩码索引:
data[(data > 0.3) & (data < 0.8)]
结果:
b 0.50
c 0.75
dtype: float64
数组索引:
data[['a', 'e']]
索引器:loc,iloc和ix
使用传统的索引方式很容易引起混淆。例如Series对象使用了整型数组进行显式声明,则data[1]将使用显式的索引,而data[1:3]还会继续使用隐式索引。
data = pd.Series(['a', 'b', 'c'], index=[1, 3, 5])
# explicit index when indexing
data[1]
# implicit index when slicing
data[1:3]
由于传统的索引容易引起混淆,所以Pandas提供了一些高级的索引器属性,这些索引器并不是函数,而是作为属性存在。
loc()
方法总是使用显式索引:
data.loc[1] # 'a'
data.loc[1:3]
结果为
1 a
3 b
dtype: object
而iloc()
总是使用隐式索引:
data.iloc[1] # 'b'
data.iloc[1:3]
结果将为:
3 b
5 c
dtype: object
ix()
将两者结合起来,对于Series对象来说它相当于[]
。
DataFrame数据选择
前面说过DataFrame既可以看做是二维数组,也可以看成Series结构的字典。
将DataFrame看做字典
例如:
area = pd.Series({'California': 423967, 'Texas': 695662,
'New York': 141297, 'Florida': 170312,
'Illinois': 149995})
pop = pd.Series({'California': 38332521, 'Texas': 26448193,
'New York': 19651127, 'Florida': 19552860,
'Illinois': 12882135})
data = pd.DataFrame({'area':area, 'pop':pop})
data
image.png
组成DataFrame的Series对象可以通过列索引获取:
data['area']
image.png
也可以像属性的方式一样获取:
data.area
属性获取的方式与通过key获取的方式类似:
data.area is data['area'] # True
注意如果采用属性获取的方式,则属性名称不能与DataFrame的方法名冲突,并且只能是字符串。例如,下面的就发生冲突了:
data.pop is data['pop']
所以一般情况下,尽量采用[]
的方式获取值。
与Series对象类似,也可以通过键赋值的方式修改整列获取添加新的列:
data['density'] = data['pop'] / data['area']
将DataFrame看做二维数组
通过values
属性可以获取原始的数据:
data.values
输出:
array([[ 4.23967000e+05, 3.83325210e+07, 9.04139261e+01],
[ 1.70312000e+05, 1.95528600e+07, 1.14806121e+02],
[ 1.49995000e+05, 1.28821350e+07, 8.58837628e+01],
[ 1.41297000e+05, 1.96511270e+07, 1.39076746e+02],
[ 6.95662000e+05, 2.64481930e+07, 3.80187404e+01]])
许多二维数组的操作同样可以在DataFrame上进行,例如通过转置交换行和列:
data.T
如果需要像普通数组一样进行切片和选择,需要使用loc
,iloc
,ix
等索引器。
例如, 使用iloc
进行隐式切片:
data.iloc[:3, :2]
结果如下:
image.png使用
loc
进行显式切片:
data.loc[:'Illinois', :'pop']
ix
支持混合切片:
data.ix[:3, :'pop']
结果如下所示:
image.png其他类似Numpy的索引方式对DataFrame也适用,例如通过掩码的方式进行索引:
data.loc[data.density > 100, ['pop', 'density']]
这些索引操作也可以用来赋值或者修改值:
data.iloc[0, 2] = 90
其它常用索引
直接对DataFrame索引获取到的是列,而切片获取的则是行:
data['Florida':'Illinois']
上述操作等价于:
data[1:3]
同样的,掩码索引针对的也是行,而不是列:
data[data.density > 100]