在 pandas 数据帧中排除索引行的最有效方法



我对Python和pandas相对较新,并且正在努力处理(分层)索引。我已经涵盖了基础知识,但迷失了更高级的切片和横截面。

例如,使用以下数据帧

import pandas as pd
import numpy as np
data = pd.DataFrame(np.arange(9).reshape((3, 3)),
    index=pd.Index(['Ohio', 'Colorado', 'New York'], name='state'), columns=pd.Index(['one', 'two', 'three'], name='number'))

我想选择除索引为"科罗拉多"的行之外的所有内容。对于一个小数据集,我可以做:

data.ix[['Ohio','New York']]

但是,如果唯一索引值的数量很大,那是不切实际的。天真地,我希望这样的语法

data.ix[['state' != 'Colorado']]

但是,这仅返回第一条记录"俄亥俄州",而不返回"纽约"。这有效,但很麻烦

filter = list(set(data.index.get_level_values(0).unique()) - set(['Colorado']))
data[filter]

肯定有一种更 Pythonic、更冗长的方法吗?

这是一个

Python问题,而不是一个pandas的问题:'state' != 'Colorado'是真的,所以pandas得到的是data.ix[[True]]

你可以做

>>> data.loc[data.index != "Colorado"]
number    one  two  three
state                    
Ohio        0    1      2
New York    6    7      8
[2 rows x 3 columns]

或使用DataFrame.query

>>> data.query("state != 'New York'")
number    one  two  three
state                    
Ohio        0    1      2
Colorado    3    4      5
[2 rows x 3 columns]

如果您不喜欢重复data. (引用传递给.query()方法的表达式是解决以下事实的唯一方法之一,否则Python会在pandas看到它之前评估比较。

这是一个强大的解决方案,也适用于 MultiIndex 对象

单一索引

excluded = ['Ohio']
indices = data.index.get_level_values('state').difference(excluded)
indx = pd.IndexSlice[indices.values]

输出

In [77]: data.loc[indx]
Out[77]:
number    one  two  three
state
Colorado    3    4      5
New York    6    7      8

多索引扩展

在这里,我扩展到一个多索引示例...

data = pd.DataFrame(np.arange(18).reshape(6,3), index=pd.MultiIndex(levels=[[u'AU', u'UK'], [u'Derby', u'Kensington', u'Newcastle', u'Sydney']], labels=[[0, 0, 0, 1, 1, 1], [0, 2, 3, 0, 1, 2]], names=[u'country', u'town']), columns=pd.Index(['one', 'two', 'three'], name='number'))

假设我们想从这个新的 MultiIndex 的两个示例中排除'Newcastle'

excluded = ['Newcastle']
indices = data.index.get_level_values('town').difference(excluded)
indx = pd.IndexSlice[:, indices.values]

这给出了预期的结果

In [115]: data.loc[indx, :]
Out[115]:
number              one  two  three
country town
AU      Derby         0    1      2
        Sydney        3    4      5
UK      Derby         0    1      2
        Kensington    3    4      5

常见陷阱

  1. 确保索引的所有级别都已排序,您需要data.sort_index(inplace=True)
  2. 确保包含列的空切片data.loc[indx, :]
  3. 有时indx = pd.IndexSlice[:, indices]就足够了,但我发现我经常需要使用indx = pd.IndexSlice[:, indices.values]

最新更新