Pandas对象的索引
可以对Pandas中的数据对象进行索引,得到数据的一部分。DataFrame和Series对象支持很多种索引方式:
import numpy as np
import pandas as pd
基于中括号的索引和切片
Pandas数据对象可以使用一对中括号“[]”进行索引操作。
在Pandas中,除了数字和字符串,时间序列也可以用来当做标记。日期时间序列可以用函数pd.date_range()创建:
dates = pd.date_range('1/1/2000', periods=8)
dates
DatetimeIndex(['2000-01-01', '2000-01-02', '2000-01-03', '2000-01-04',
'2000-01-05', '2000-01-06', '2000-01-07', '2000-01-08'],
dtype='datetime64[ns]', freq='D')
通过指定index参数,可以构建一个基于时间序列的DataFrame对象:
df = pd.DataFrame(np.random.randn(8, 4),
index=dates,
columns=['A', 'B', 'C', 'D'])
df
A | B | C | D | |
---|---|---|---|---|
2000-01-01 | -0.681137 | -0.160976 | 0.234236 | -2.174047 |
2000-01-02 | 0.231262 | 2.145968 | -1.485805 | 1.616187 |
2000-01-03 | 0.879341 | -0.120279 | -0.370795 | 0.738800 |
2000-01-04 | 1.508886 | 0.266039 | 1.269122 | -0.495479 |
2000-01-05 | -1.007768 | -0.189645 | -1.206941 | 1.050181 |
2000-01-06 | 1.610657 | -0.592687 | -2.295021 | 0.503928 |
2000-01-07 | 0.514324 | 1.002499 | 0.464693 | 1.156294 |
2000-01-08 | -0.972601 | -0.465772 | 0.908502 | 0.071828 |
对于Series对象来说,中括号索引标记返回一个标量;对于DataFrame对象来说,中括号索引列标记,返回该列对应的一个Series对象:
s = df['A']
s
2000-01-01 -0.681137
2000-01-02 0.231262
2000-01-03 0.879341
2000-01-04 1.508886
2000-01-05 -1.007768
2000-01-06 1.610657
2000-01-07 0.514324
2000-01-08 -0.972601
Freq: D, Name: A, dtype: float64
s[dates[5]]
1.6106574534144948
中括号索引还支持用列标记列表操作,得到一个DataFrame对象:
df[['A', 'B']]
A | B | |
---|---|---|
2000-01-01 | -0.681137 | -0.160976 |
2000-01-02 | 0.231262 | 2.145968 |
2000-01-03 | 0.879341 | -0.120279 |
2000-01-04 | 1.508886 | 0.266039 |
2000-01-05 | -1.007768 | -0.189645 |
2000-01-06 | 1.610657 | -0.592687 |
2000-01-07 | 0.514324 | 1.002499 |
2000-01-08 | -0.972601 | -0.465772 |
当列标记的名称是一个合法的Python对象名时,在不跟DataFrame对象自带的方法和属性名冲突的情况下,Pandas会自动将该名称转化为一个属性:
df.C
2000-01-01 0.234236
2000-01-02 -1.485805
2000-01-03 -0.370795
2000-01-04 1.269122
2000-01-05 -1.206941
2000-01-06 -2.295021
2000-01-07 0.464693
2000-01-08 0.908502
Freq: D, Name: C, dtype: float64
Series对象也支持使用标记名称进行属性索引:
sa = pd.Series([1,2,3],index=list('abc'))
sa.b
2
Series对象支持切片操作:
s[:5]
2000-01-01 -0.681137
2000-01-02 0.231262
2000-01-03 0.879341
2000-01-04 1.508886
2000-01-05 -1.007768
Freq: D, Name: A, dtype: float64
s[::2]
2000-01-01 -0.681137
2000-01-03 0.879341
2000-01-05 -1.007768
2000-01-07 0.514324
Freq: 2D, Name: A, dtype: float64
以及高级的切片操作:
s['20000101':'20000103']
2000-01-01 -0.681137
2000-01-02 0.231262
2000-01-03 0.879341
Freq: D, Name: A, dtype: float64
基于位置和标记的高级索引
在中括号索引时,DataFrame对象会存在列索引和行索引混用的情况:
- 单值:索引列。
- 列表:索引多列。
- slice对象:索引多行。
为了避免混淆,DataFrame对象提供了另一套高级索引来处理这些情况。
df
A | B | C | D | |
---|---|---|---|---|
2000-01-01 | -0.681137 | -0.160976 | 0.234236 | -2.174047 |
2000-01-02 | 0.231262 | 2.145968 | -1.485805 | 1.616187 |
2000-01-03 | 0.879341 | -0.120279 | -0.370795 | 0.738800 |
2000-01-04 | 1.508886 | 0.266039 | 1.269122 | -0.495479 |
2000-01-05 | -1.007768 | -0.189645 | -1.206941 | 1.050181 |
2000-01-06 | 1.610657 | -0.592687 | -2.295021 | 0.503928 |
2000-01-07 | 0.514324 | 1.002499 | 0.464693 | 1.156294 |
2000-01-08 | -0.972601 | -0.465772 | 0.908502 | 0.071828 |
df.loc[dates[1]]
A 0.231262
B 2.145968
C -1.485805
D 1.616187
Name: 2000-01-02 00:00:00, dtype: float64
日期类型还使用一个字符串进行索引,只要这个字符串符合日期的格式,如:
df.loc['20000102']
A 0.231262
B 2.145968
C -1.485805
D 1.616187
Name: 2000-01-02 00:00:00, dtype: float64
df.loc['20000102':'20000104']
A | B | C | D | |
---|---|---|---|---|
2000-01-02 | 0.231262 | 2.145968 | -1.485805 | 1.616187 |
2000-01-03 | 0.879341 | -0.120279 | -0.370795 | 0.738800 |
2000-01-04 | 1.508886 | 0.266039 | 1.269122 | -0.495479 |
与数字切片只包含开头不包含结尾的结果不同,.loc
属性的行切片结果包含结尾。
.loc
属性还可以额外接受列标记进行索引。例如:
df.loc['20000101', 'A']
-0.6811372986010428
df.loc['20000101', ['A', 'C']]
A -0.681137
C 0.234236
Name: 2000-01-01 00:00:00, dtype: float64
df.loc['20000107':, ['A', 'C']]
A | C | |
---|---|---|
2000-01-07 | 0.514324 | 0.464693 |
2000-01-08 | -0.972601 | 0.908502 |
.loc
属性基于标记对DataFrame对象进行索引,而.iloc
属性则基于位置对DataFrame对象进行索引。例如,用.iloc
属性索引第二行的数据:
df.iloc[1]
A 0.231262
B 2.145968
C -1.485805
D 1.616187
Name: 2000-01-02 00:00:00, dtype: float64
df.iloc[1, 0]
0.23126158547402592
与.loc属性不同的是,.iloc的切片不包含最后一个元素。
如果只需要索引单个值,最快速的方法是使用.at
索引标记:
df.at[dates[5], 'A']
1.6106574534144948
或者用.iat
索引位置:
df.iat[5, 0]
1.6106574534144948
Pandas支持基于布尔值的条件对Series进行进行索引。例如,使用布尔值条件s>0索引,来得到Series对象中所有大于0的值:
s = df["A"]
s[s > 0]
2000-01-02 0.231262
2000-01-03 0.879341
2000-01-04 1.508886
2000-01-06 1.610657
2000-01-07 0.514324
Name: A, dtype: float64
还可以使用取反符号~
,使用取反表达式~(s>0)
进行索引,得到所有小于等于0的值:
s[~(s > 0)]
2000-01-01 -0.681137
2000-01-05 -1.007768
2000-01-08 -0.972601
Name: A, dtype: float64
DataFrame对象的行也可以通过布尔值条件索引。比如,索引所有A列大于0的行:
df[df["A"] > 0]
A | B | C | D | |
---|---|---|---|---|
2000-01-02 | 0.231262 | 2.145968 | -1.485805 | 1.616187 |
2000-01-03 | 0.879341 | -0.120279 | -0.370795 | 0.738800 |
2000-01-04 | 1.508886 | 0.266039 | 1.269122 | -0.495479 |
2000-01-06 | 1.610657 | -0.592687 | -2.295021 | 0.503928 |
2000-01-07 | 0.514324 | 1.002499 | 0.464693 | 1.156294 |