3.3 数据取值与选择
本篇介绍Pandas的Series和DataFrame对象的数据获取与调整操作.
一、Series数据选择方法
Series对象与一维Numpy数组和标准字典在许多方面都一样。
1.将Series看做字典
和字典一样,Series 对象提供了键值对的映射:
In[1] : import pandas as pd
import numpy as np
In[2] : data = pd.Series([0.25,0.5,0.75,1],index=["a","b","c","d"])
data
Out[2]: a 0.25
b 0.50
c 0.75
d 1.00
dtype: float64
In[3] : data['b']
Out[3]: 0.5
我们还可以用Python 字典的表达式和方法来检测键/ 索引和值:
In[4] : 'a' in data
Out[4]: True
In[5] : data.keys()
Out[5]: Index(['a', 'b', 'c', 'd'], dtype='object')
In[6] : data.items()
Out[6]: <zip at 0x25da40d18c8>
In[7] : list(data.items())
Out[7]: [('a', 0.25), ('b', 0.5), ('c', 0.75), ('d', 1.0)]
Series 对象还可以用字典语法调整数据。就像你可以通过增加新的键扩展字典一样,你也可以通过增加新的索引值扩展Series:
In[8] : data['e'] = 1.25
data
Out[8]: a 0.25
b 0.50
c 0.75
d 1.00
e 1.25
dtype: float64
2.将Series看做一维数组
Series 不仅有着和字典一样的接口,而且还具备和NumPy 数组一样的数组数据选择功能,包括索引、掩码、花哨的索引等操作,具体示例如下所示:
# 将显式索引作为切片
In[9] : data["a":"c"]
Out[9]: a 0.25
b 0.50
c 0.75
dtype: float64
# 将隐式整数索引作为切片
In[10] : data[0:2]
Out[10]: a 0.25
b 0.50
dtype: float64
# 掩码
In[11] : data[(data > 0.3) & (data < 0.8)]
Out[11]: b 0.50
c 0.75
dtype: float64
# 花哨的索引
In[12] : data[['a','e']]
Out[12]: a 0.25
e 1.25
dtype: float64
注意:当使用显示索引做切片时,结果包含最后一个索引;而当使用隐式索引作切片时,结果不包含最后一个索引。
3.索引器:loc、iloc
以上的索引方式有时会出现混乱,不符合我们的预期结果。比如,当我们的Series是显示整数索引,那么data[1]这样取值方式默认仿作显示索引去取值,而切片操作(如data[1:3])却会使用隐式索引取值。
显式索引:基于标签的索引
隐式索引:基于位置的索引
In[13] :data = pd.Series(['a','b','c'],index = [1,3,5])
data
Out[13]: 1 a
3 b
5 c
dtype: object
In[14] : data[1] # 取值操作是显式索引
Out[14]: 'a'
In[15] : data[1:3] # 切片操作是隐式索引
Out[15]: 3 b
5 c
dtype: object
为此,Pandas提供了索引器属性来作为取值的方法。不是方法,而是属性
①.loc属性,表示取值和切片都是显式的:
In[15] : data.loc[1] # 显式取值
Out[16]: 'a'
In[15] : data.loc[1:3] #显式切片
Out[17]: 1 a
3 b
dtype: object
②.iloc属性,表示取值和切片都是隐式索引:
In[16] : data.iloc[1] # 隐式取值
Out[16]: 'b'
In[17] : data.iloc[1:3] #隐式切片
Out[17]: 3 b
5 c
dtype: object
二、DataFrame数据选择方法
DataFrame 在有些方面像二维或结构化数组,在有些方面又像一个共享索引的若干Series 对象构成的字典。这两种类比可以帮助我们更好地掌握这种数据结构的数据选择方法。
1.将DataFrame看作字典
In[18] : 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
Out[18]:
area pop
California 423967 38332521
Texas 695662 26448193
New York 141297 19651127
Florida 170312 19552860
Illinois 149995 12882135
两个Series分别构成DF的一列,我们可以通过列名作为key进行形式的取值获取一列数据:
In[19] : data['area']
Out[19]:
California 423967
Texas 695662
New York 141297
Florida 170312
Illinois 149995
Name: area, dtype: int64
也可以使用属性形式选择纯字符串列名的数据(可能数整数列名或者与方法名重名的列名时容易发生混淆),这两者是相等的:
In[19] : data.area
Out[19]:
California 423967
Texas 695662
New York 141297
Florida 170312
Illinois 149995
Name: area, dtype: int64
In[20] : data.area is data['area']
Out[20]: True
2.将DataFrame看作二维数组
可以把DF看作是一个加强版的二维数组,用values属性按行查看数组数据:
In[21] : data.values
Out[21]: array([[ 423967, 38332521],
[ 695662, 26448193],
[ 141297, 19651127],
[ 170312, 19552860],
[ 149995, 12882135]], dtype=int64)
In[22] : data.values[0] # 获取一行数据
Out[22]: array([ 423967, 38332521], dtype=int64)
In[23] : data['area'] # 获取一列数据
Out[23]:
California 423967
Texas 695662
New York 141297
Florida 170312
Illinois 149995
Name: area, dtype: int64
为了更方便的选取我们 想要的行和列数据,我们可以使用另一种方法:显式索引器loc、隐式索引器iloc和混合索引器ix。
In[24] : data.iloc[:3, :2] # dataframe隐式索引切片
Out[24]:
area pop
California 423967 38332521
Texas 695662 26448193
New York 141297 19651127
In[25] :data.loc[:'New York', :'pop'] # dataframe显式索引切片
Out[25]:
area pop
California 423967 38332521
Texas 695662 26448193
New York 141297 19651127
使用ix 索引器可以实现一种混合效果:(.ix在Python3中已启用,推荐使用.loc和.iloc,不过仍能使用。)
In[26] : data.ix[:3, :'pop']
Out[26]:
area pop
California 423967 38332521
Texas 695662 26448193
New York 141297 19651127