在pandas datafram中排除索引行的最有效方法

2024-04-26 11:55:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我对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'))

我要选择除索引为“Colorado”的行之外的所有行。对于一个小数据集,我可以做到:

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

但如果唯一索引值的数量很大,那就不切实际了。天真地说,我希望

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

然而,这只返回第一个记录“俄亥俄州”,而不返回“纽约”。这很管用,但很麻烦

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

当然有一种更像Python的,冗长的方式来做这件事吗?


Tags: 数据nameimportpandasnewdataindexas
2条回答

这是一个健壮的解决方案,也适用于多索引对象

单一索引

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'))

假设我们要从这个新的多索引的两个示例中排除'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]

这是一个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]

或者使用^{}

>>> 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看到比较之前对其求值。)

相关问题 更多 >