【问题标题】:Most efficient way to exclude indexed rows in pandas dataframe在熊猫数据框中排除索引行的最有效方法
【发布时间】:2017-08-03 23:09:50
【问题描述】:

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

但是,这只会返回第一条记录“Ohio”,而不会返回“New York”。这可行,但很麻烦

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

肯定有一种更 Pythonic、更冗长的方式来做到这一点?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    这是一个 Python 问题,而不是 pandas 一个:'state' != 'Colorado' 是 True,所以 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 看到它之前评估比较。)

    【讨论】:

      【解决方案2】:

      这是一个强大的解决方案,也适用于 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
      

      多索引扩展

      这里我扩展了一个 MultiIndex 示例...

      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]

      【讨论】:

        猜你喜欢
        • 2020-07-24
        • 2018-01-02
        • 2021-01-17
        • 2019-02-22
        • 2021-03-20
        • 1970-01-01
        • 2015-06-13
        • 1970-01-01
        相关资源
        最近更新 更多