【问题标题】:Filter by combination of three columns the n first values按 n 个第一个值的三列组合过滤
【发布时间】:2019-09-30 14:40:23
【问题描述】:

我有一个排序的数据框,有 4 列,如下所示。我正在尝试过滤我的数据框,以便对于(Var1,Var2,Var3)的每个组合,我保留 Var4 的 2 个第一个不同值。 例如,我在 Dataframe 中拥有的 (Var1, Var2, Var3) 的第一个组合是 (A, B, C)。此组合的前两个不同值是 value_1 和 value_2。 (Var1, Var2, Var3) 的第二个组合是 (A, C, C)。对于这种组合,我只有一种类型的值,即 value_14。 等等……

输入:

       Var1  Var2  Var3  Var4
    1     A    B      C  value_1
    2     A    B      C  value_1
    3     A    B      C  value_1
    4     A    B      C  value_1
    5     A    B      C  value_2
    6     A    B      C  value_2
    7     A    B      C  value_3
    8     A    B      C  value_3
    9     A    B      C  value_3
    10    A    B      C  value_4
   11     A    C      C  value_14
   12     A    C      C  value_14
   13     A    C      C  value_14
   14     A    C      C  value_14
   15     B    B      C  value_21
   16     B    B      C  value_21
   17     B    B      C  value_32
   18     B    B      C  value_32
   19     B    B      C  value_33
   20     B    B      C  value_43

输出:

       Var1  Var2  Var3  Var4
    1     A    B      C  value_1
    2     A    B      C  value_1
    3     A    B      C  value_1
    4     A    B      C  value_1
    5     A    B      C  value_2
    6     A    B      C  value_2
   11     A    C      C  value_14
   12     A    C      C  value_14
   13     A    C      C  value_14
   14     A    C      C  value_14
   15     B    B      C  value_21
   16     B    B      C  value_21
   17     B    B      C  value_32
   18     B    B      C  value_32

请注意,我的数据框有 500 万行。到目前为止,我已经找到了一个使用循环的解决方案,但这需要将近一个小时。

【问题讨论】:

    标签: pandas


    【解决方案1】:

    我们可以使用

    df[df.groupby(['Var1','Var2','Var3'])['Var4'].apply(lambda x : x.groupby(x).ngroup()<2)]
    
    Out[106]: 
       Var1 Var2 Var3      Var4
    1     A    B    C   value_1
    2     A    B    C   value_1
    3     A    B    C   value_1
    4     A    B    C   value_1
    5     A    B    C   value_2
    6     A    B    C   value_2
    11    A    C    C  value_14
    12    A    C    C  value_14
    13    A    C    C  value_14
    14    A    C    C  value_14
    15    B    B    C  value_21
    16    B    B    C  value_21
    17    B    B    C  value_32
    18    B    B    C  value_32
    

    【讨论】:

      【解决方案2】:

      ngroup 标记组,然后我们通过减去最小值来确保每个组从 0 开始。然后是一个简单的面具。

      s = df.groupby([*df], sort=False).ngroup()  #sort = False keeps ordering of Val4
      s = s - s.groupby([df.Var1, df.Var2, df.Var3]).transform('min')
      
      df[s.le(1)]
      

         Var1 Var2 Var3      Var4
      1     A    B    C   value_1
      2     A    B    C   value_1
      3     A    B    C   value_1
      4     A    B    C   value_1
      5     A    B    C   value_2
      6     A    B    C   value_2
      11    A    C    C  value_14
      12    A    C    C  value_14
      13    A    C    C  value_14
      14    A    C    C  value_14
      15    B    B    C  value_21
      16    B    B    C  value_21
      17    B    B    C  value_32
      18    B    B    C  value_32
      

      【讨论】:

        【解决方案3】:

        让我们使用这个方法:

        df.drop_duplicates(['Var1','Var2','Var3','Var4'])\
          .groupby(['Var1','Var2','Var3']).head(2)\
          .merge(df, on=['Var1','Var2','Var3','Var4'])
        

        输出:

           Var1 Var2 Var3      Var4
        0     A    B    C   value_1
        1     A    B    C   value_1
        2     A    B    C   value_1
        3     A    B    C   value_1
        4     A    B    C   value_2
        5     A    B    C   value_2
        6     A    C    C  value_14
        7     A    C    C  value_14
        8     A    C    C  value_14
        9     A    C    C  value_14
        10    B    B    C  value_21
        11    B    B    C  value_21
        12    B    B    C  value_32
        13    B    B    C  value_32
        

        【讨论】:

        • 不确定这对于您的数据集是否会更快。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-04
        • 1970-01-01
        • 2011-03-22
        • 1970-01-01
        • 2010-12-19
        相关资源
        最近更新 更多