【问题标题】:Pandas: filter on multiple columns [duplicate]Pandas:过滤多列[重复]
【发布时间】:2018-03-21 02:06:48
【问题描述】:

我在 Pandas 中工作,我想将多个过滤器应用于跨多个字段的数据框。

我正在使用另一个更复杂的数据框,但我正在简化这个问题的上下文。以下是示例数据框的设置:

dates = pd.date_range('20170101', periods=16)
rand_df = pd.DataFrame(np.random.randn(16,4), index=dates, columns=list('ABCD'))

对此数据框应用一个过滤器有据可查且简单:

rand_df.loc[lambda df: df['A'] < 0]

因为 lambda 看起来像一个简单的布尔表达式。执行以下操作很诱人。这不起作用,因为它不是布尔表达式,而是可调用的。其中多个不能像布尔表达式那样组合:

rand_df.loc[lambda df: df['A'] < 0 and df[‘B’] < 0]

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-31-dfa05ab293f9> in <module>()
----> 1 rand_df.loc[lambda df: df['A'] < 0 and df['B'] < 0]

我找到了两种成功实现这一点的方法。我会将它们添加到潜在答案中,因此您可以直接评论它们作为解决方案。但是,我想征求其他方法,因为我不确定这两种方法是否是过滤 Pandas 数据帧的非常标准的方法。

【问题讨论】:

  • UN-DUPLICATE:被标记为重复的问题确实回答了我的问题。然而,它没有这个干净。该问题有一些多余的上下文,例如数据是从 CSV 读取的。这是一个干净的示例,您可以将代码直接粘贴到您自己的 REPL 中,提出答案并发布。在很短的时间内,这个问题的答案比重复的提名人还要多。因此,我认为重新开放是有意义的。
  • 问题完全相同,重复的答案是由 pandas 的创建者编写的,所以我认为这是过滤数据框的最佳方法。
  • 谢谢。谦虚地指出,我应该考虑特别重视 Wes McKinney 回答的 Pandas 问题。

标签: python pandas filtering


【解决方案1】:

这是一种“链式”使用“loc”操作的方法:

rand_df.loc[lambda df: df['A'] < 0].loc[lambda df: df['B'] < 0]

【讨论】:

    【解决方案2】:
    rand_df[(rand_df.A < 0) & (rand_df.B <0)]
    

    【讨论】:

      【解决方案3】:
      In [3]: rand_df.query("A < 0 and B < 0")
      Out[3]:
                         A         B         C         D
      2017-01-02 -0.701682 -1.224531 -0.273323 -1.091705
      2017-01-05 -1.262971 -0.531959 -0.997451 -0.070095
      2017-01-06 -0.065729 -1.427199  1.202082  0.136657
      2017-01-08 -1.445050 -0.367112 -2.617743  0.496396
      2017-01-12 -1.273692 -0.456254 -0.668510 -0.125507
      

      或:

      In [6]: rand_df[rand_df[['A','B']].lt(0).all(1)]
      Out[6]:
                         A         B         C         D
      2017-01-02 -0.701682 -1.224531 -0.273323 -1.091705
      2017-01-05 -1.262971 -0.531959 -0.997451 -0.070095
      2017-01-06 -0.065729 -1.427199  1.202082  0.136657
      2017-01-08 -1.445050 -0.367112 -2.617743  0.496396
      2017-01-12 -1.273692 -0.456254 -0.668510 -0.125507
      

      PS 你会在the Pandas docs找到很多例子

      【讨论】:

      • 这个抓住了问题的本质:避免多次引用封闭的数据框
      【解决方案4】:

      这是一种方法,其中包括编写一种方法来进行过滤。我确信某些过滤器会足够复杂或复杂到该方法是最好的方法(这种情况不是那么复杂。)另外,当我使用 Pandas 并编写“for”循环时,我觉得我我做错了。

      def lt_zero_ab(df):
          result = []
          for index, row in df.iterrows():
              if row['A'] <0 and row['B'] <0:
                  result.append(index)
          return result
      rand_df.loc[lt_zero_ab]
      

      【讨论】:

        【解决方案5】:

        要使用lambda,请不要传递整个列。

        rand_df.loc[lambda x: (x.A < 0) & (x.B < 0)]
        # Or
        # rand_df[lambda x: (x.A < 0) & (x.B < 0)]
        
                           A         B         C         D
        2017-01-12 -0.460918 -1.001184 -0.796981  0.328535
        2017-01-14 -0.146846 -1.088095 -1.055271 -0.778120
        

        您可以使用布尔 numpy 数组加快评估速度

        c1 = rand_df.A.values > 0
        c2 = rand_df.B.values > 0
        rand_df[c1 & c2]
        
                           A         B         C         D
        2017-01-12 -0.460918 -1.001184 -0.796981  0.328535
        2017-01-14 -0.146846 -1.088095 -1.055271 -0.778120
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-01-29
          • 1970-01-01
          • 2020-12-01
          • 2015-12-13
          • 2018-01-02
          • 2018-11-14
          • 2020-04-23
          • 2019-07-25
          相关资源
          最近更新 更多