Pandas Index索引的用途可以总结为:

  • 更方便的数据查询;
  • 使用index可以获得性能提升;
  • 自动的数据对齐功能;
  • 更多更强大的数据结构支持;

Pandas支持3种类型的多轴索引,即lociloc,和[]ix,在0.20.0版本之后,ix被弃用,可按照需求采用lociloc索引数据)。

loc

主要是基于标签的(即真实索引),但也可以与布尔数组一起使用。.loc()具有多种访问方式,如 :

  • 单个标签,例如5'a'(注意,整数是有效的标签,但它们是指标签而不是位置)。
  • 列表或标签数组。['a', 'b', 'c']
  • 带标签的切片对象'a':'f'(切片时,也包括起始边界)
  • 布尔数组
  • 一个callable带有一个参数的函数(调用Series或DataFrame)并返回有效的索引输出(以上的其中一种)。

举例

s = pd.Series(np.arange(5), index=list('abcde'), dtype='int64')
print(s)
"""
a    0
b    1
c    2
d    3
e    4
dtype: int64
"""
print(s.loc['a'])  # 0
print(s.loc['b':])  
"""
b    1
c    2
d    3
e    4
dtype: int64
"""
s.loc['b':] = 0
print(s)
"""
a    0
b    0
c    0
d    0
e    0
dtype: int64
"""
df = pd.DataFrame(np.random.randn(6, 4), index=list('abcdef'), columns=list('ABCD'))
print(df)
"""
          A         B         C         D
a  0.469699  0.757555  2.369428 -1.076540
b  0.351754 -0.508842  0.159646 -1.109521
c  1.601835 -0.108725  1.232134 -1.047540
d  1.810829 -1.084219 -1.208421  0.451652
e  0.913897 -0.024905  0.532991 -0.525929
f  0.237053  0.245523 -0.030416  0.337695
"""
print(df.loc['a'])
"""
A    0.469699
B    0.757555
C    2.369428
D   -1.076540
Name: a, dtype: float64
"""
print(df.loc['a'] > 0)
"""
A     True
B     True
C     True
D    False
Name: a, dtype: bool
"""
print(df.loc[['a', 'b', 'c'], :])
"""
          A         B         C         D
a  0.469699  0.757555  2.369428 -1.076540
b  0.351754 -0.508842  0.159646 -1.109521
c  1.601835 -0.108725  1.232134 -1.047540

"""

iloc

主要是基于整数位置的(即索引序号),但也可以使用布尔值阵列。具有多种访问方式,如 :

  • 一个整数,例如5
  • 整数列表或数组。[4, 3, 0]
  • 带有整数的切片对象1:7
  • 布尔数组。
  • 一个callable带有一个参数的函数(调用Series或DataFrame)并返回有效的索引输出(以上的其中一种)。

举例

s = pd.Series(np.arange(5), index=list('abcde'), dtype='int64')
print(s)
"""
a    0
b    1
c    2
d    3
e    4
dtype: int64
"""
print(s.iloc[2])  # 2
print(s.iloc[:2])
"""
a    0
b    1
dtype: int64
"""
s.iloc[:2] = 0
print(s)
"""
a    0
b    0
c    0
d    0
e    0
dtype: int64
"""

使用DataFrame:

df = pd.DataFrame(np.random.randn(6, 4), index=list('abcdef'), columns=list('ABCD'))
print(df)
"""
          A         B         C         D
a -0.924837 -0.844862  0.736636 -0.390307
b -0.309918  2.216527 -1.445908 -0.742897
c -0.247190 -0.109978 -1.038569  0.435933
d  0.744125  0.742345  0.192453 -0.091611
e  0.176130  1.366126 -2.927570  0.754103
f -0.115015  0.589704 -1.090251  1.152097
"""
print(df.iloc[0])
"""
A   -0.924837
B   -0.844862
C    0.736636
D   -0.390307
Name: a, dtype: float64
"""
print(df.iloc[0] > 0)
"""
A    False
B    False
C     True
D    False
Name: a, dtype: bool
"""
print(df.iloc[1:5, 2:4])
"""
          C         D
b -1.445908 -0.742897
c -1.038569  0.435933
d  0.192453 -0.091611
e -2.927570  0.754103
"""
print(df.iloc[[1, 3, 5], [1, 3]])
"""
          B         D
b  2.216527 -0.742897
d  0.742345 -0.091611
f  0.589704  1.152097
"""

atiat

loc类似,at也是基于标签的,同时iat类似于基于整数的iloc

isin

查看某个值或者索引的值是否存在,该方法返回一个布尔向量

s = pd.Series(np.arange(5), index=np.arange(5)[::-1], dtype='int64')
#np.arange(5)[::-1]是反转数组
print(s)
"""
4    0
3    1
2    2
1    3
0    4
dtype: int64
"""
print(s.isin([2, 4, 6]))
"""
4    False
3    False
2     True
1    False
0     True
dtype: bool
"""
print(s[s.isin([2, 4, 6])])
"""
2    2
0    4
dtype: int64
"""

在实际中,有时候并不知道index的具体信息,也可以使用isin判断索引是否存在

print(s[s.index.isin([2, 4, 6])])#查找索引为2,4,6对于的值
"""
4    0
2    2
dtype: int64
"""

而同样适用于多重索引MultiIndex中,例如

s1 = pd.Series(np.arange(10), index=pd.MultiIndex.from_product([[0, 1], ['a', 'b', 'c', 'd', 'e']]))
print(s1)
"""
0  a    0
   b    1
   c    2
   d    3
   e    4
1  a    5
   b    6
   c    7
   d    8
   e    9
dtype: int32
"""
print(s1[s1.index.isin([(1, 'a'), (2, 'b'), (3, 'c')])])
"""
1  a    5
dtype: int32
"""

下面看看DataFrame的isin,如果values是一个数组,则isin返回与原始DataFrame形状相同的布尔数据框。

df = pd.DataFrame({'vals': [1, 2, 3, 4], 'ids': ['a', 'b', 'f', 'n'], 'ids2': ['a', 'n', 'c', 'n']})
values = ['a', 'b', 1, 3]
print(df.isin(values))
"""
    vals    ids   ids2
0   True   True   True
1  False   True  False
2   True  False  False
3  False  False  False
"""

可以配合any()all()方法来快速选择符合给定的标准对数据子集

where

s = pd.Series(data=np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
print(s)
"""
a    0.036334
b   -1.705168
c   -1.846465
d    1.350649
e    0.055091
dtype: float64
"""
print(s[s < 0])
"""
b   -1.705168
c   -1.846465
dtype: float64
"""
print(s.where(s < 0))
"""
a         NaN
b   -1.705168
c   -1.846465
d         NaN
e         NaN
dtype: float64
"""
df = pd.DataFrame(np.random.randn(5, 4), columns=['A', 'B', 'C', 'D'])
print(df)
"""
          A         B         C         D
0 -0.080725  0.389280  0.859920  3.031320
1 -0.652758  0.461458 -0.680639  2.072086
2 -0.647795  0.978124  0.144277 -0.638548
3 -1.593368 -0.040756 -0.488344  0.079780
4 -2.915217 -0.212025 -1.311406  1.200810
"""
print(df[df < 0])
"""
          A         B         C         D
0 -0.080725       NaN       NaN       NaN
1 -0.652758       NaN -0.680639       NaN
2 -0.647795       NaN       NaN -0.638548
3 -1.593368 -0.040756 -0.488344       NaN
4 -2.915217 -0.212025 -1.311406       NaN
"""
print(df.where(df < 0))
"""
          A         B         C         D
0 -0.080725       NaN       NaN       NaN
1 -0.652758       NaN -0.680639       NaN
2 -0.647795       NaN       NaN -0.638548
3 -1.593368 -0.040756 -0.488344       NaN
4 -2.915217 -0.212025 -1.311406       NaN
"""

其他具体可以参考官方文档。

query

DataFrame提供query方法允许使用表达式进行数据选取。

df = pd.DataFrame(np.random.rand(5, 3), columns=['A', 'B', 'C'])
print(df)
"""
          A         B         C
0  0.262805  0.960896  0.276461
1  0.088881  0.169215  0.465360
2  0.678148  0.492864  0.137100
3  0.494619  0.765754  0.261780
4  0.675247  0.752663  0.709871
"""
print(df[(df.A < df.B) & (df.B < df.C)])
"""
          A         B        C
1  0.088881  0.169215  0.46536
"""
print(df[(df.A < df.B) & (df.B < df.C)] == df.query('(A<B<C)'))
# df[(df.A < df.B) & (df.B < df.C)]等同于 df.query('(A<B) & (B<C)')
"""
      A     B     C
1  True  True  True
"""

如果没有名称的列,则执行相同的操作但返回索引名称a

df = pd.DataFrame(np.random.rand(5, 3), columns=['A', 'B', 'C'])
df.index.name = 'a'
print(df)
"""
          A         B         C
a                              
0  0.516509  0.529194  0.965933
1  0.922649  0.382211  0.383656
2  0.710264  0.601778  0.386659
3  0.199166  0.616787  0.817979
4  0.404193  0.077953  0.319721
"""

print(df.query('( a < B < C )'))
"""
          A         B         C
a                              
0  0.516509  0.529194  0.965933
"""

如果您不希望或不能命名索引,则可以使用 'index':

df = pd.DataFrame(np.random.rand(5, 3), columns=['A', 'B', 'C'])
print(df)
"""
          A         B         C
0  0.231783  0.752778  0.763465
1  0.313005  0.410736  0.928091
2  0.607272  0.311927  0.989749
3  0.104900  0.026600  0.575775
4  0.523358  0.132647  0.750618
"""

print(df.query('(index < B < C)'))
"""
          A         B         C
0  0.231783  0.752778  0.763465
"""

如果索引的名称与列名称重叠,则列名称优先;也可以使用特殊标识符 'index'

df = pd.DataFrame(np.random.rand(5, 3), columns=['A', 'B', 'C'])
df.index.name = 'A'
print(df)
"""
          A         B         C
A                              
0  0.202598  0.782984  0.913703
1  0.749658  0.946730  0.032033
2  0.240811  0.688982  0.235367
3  0.041943  0.799996  0.404671
4  0.471568  0.145648  0.379349
"""

print(df.query('A > 0.5'))
"""
          A        B         C
A                             
1  0.749658  0.94673  0.032033
"""
print(df.query('index > 0.5'))
"""
          A         B         C
A                              
1  0.749658  0.946730  0.032033
2  0.240811  0.688982  0.235367
3  0.041943  0.799996  0.404671
4  0.471568  0.145648  0.379349
"""

get

Series或DataFrame都提供一个get,可以返回默认值的方法。

s = pd.Series(data=np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
print(s)
"""
a   -0.078789
b   -0.987079
c    0.347506
d    1.299694
e   -1.383272
dtype: float64
"""
print(s.get('a')) #-0.07878905486063005,可以设置default=-1

df = pd.DataFrame.from_dict(dict([('A', [1, 2, 3]), ('B', [4, 5, 6])]), orient='index', columns=['a', 'b', 'c'])
print(df)
"""
   a  b  c
A  1  2  3
B  4  5  6
"""
print(df.get('a'))
"""
A    1
B    4
Name: a, dtype: int64
"""

lookup

高级的索引方式,仅适用于DataFrame。给定的行和列标签数组长度是相等的,返回对应于每个(行,列)一对的值的数组。

df = pd.DataFrame(np.random.rand(20, 4), columns=['A', 'B', 'C', 'D'])
print(df)
"""
           A         B         C         D
0   0.140680  0.090249  0.856025  0.372685
1   0.003483  0.212248  0.473694  0.448281
2   0.275576  0.070727  0.024614  0.649417
3   0.541142  0.683731  0.452914  0.634844
4   0.092144  0.531721  0.992580  0.148160
5   0.435356  0.359170  0.757804  0.872095
6   0.841636  0.103978  0.781045  0.414116
7   0.290041  0.817660  0.440186  0.990049
8   0.533673  0.134341  0.685136  0.790448
9   0.356519  0.660389  0.498869  0.853177
10  0.433663  0.894910  0.801654  0.146775
11  0.591647  0.782684  0.718427  0.646008
12  0.729917  0.175254  0.493607  0.715460
13  0.442146  0.721788  0.758316  0.425173
14  0.304630  0.530807  0.643836  0.071652
15  0.822386  0.946926  0.151597  0.444338
16  0.425350  0.726438  0.100328  0.757651
17  0.066900  0.981867  0.933085  0.487493
18  0.371977  0.646238  0.793118  0.531412
19  0.603142  0.479281  0.134921  0.202139
"""
print(df.lookup(list(range(0, 10, 2)), ['B', 'C', 'A', 'B', 'D']))
#行的范围为0~10(不包含10),2为间隔,提取的行为0,2,4,6,8,对应的列数组为BCABD,所要提取的数据索引为B0,C2,A4,B6,D8
"""
[0.09024937 0.02461377 0.0921435  0.10397808 0.79044818]
"""