【问题标题】:Remove duplicate rows but with condition删除重复的行但有条件
【发布时间】:2022-11-10 15:59:14
【问题描述】:

我有一个看起来像这样的数据框:

df =

date         col1    col2    col3    col4
-----------------------------------------
2022/30/01   2       2       4       5
2022/30/01   2       2       4       5
2022/30/01   0       0       1       2
2022/30/01   0       0       1       2
2022/30/01   3       2       4       2
2022/30/01   5       8       4       3

所以基本上我的前两行是相同的,接下来的两行也是相同的,最后两行是不同的。

我想做的是删除重复的行,但只有那些col1col2等于0的行,即生成的数据框应该是:

df_final =

date         col1    col2    col3    col4
-----------------------------------------
2022/30/01   2       2       4       5
2022/30/01   2       2       4       5
2022/30/01   0       0       1       2
2022/30/01   3       2       4       2
2022/30/01   5       8       4       3

有什么方法可以轻松地完成此任务吗?我知道我可能可以对数据框进行某种排序,然后遍历每一行并检查条件。我只是怀疑如果有很多行,这可能是一个相当耗时的过程。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    IIUC,这是通过布尔掩码进行的简单选择,使用 duplicated 查找重复行并使用 ne+all 过滤 0 值:

    # is the row not a duplicate?
    mask1 = ~df.duplicated()
    # are col1 and col2 not both 0?
    mask2 = df[['col1', 'col2']].ne(0).all(axis=1)
    # then keep the data on either of the above conditions
    df2 = df[mask1|mask2]
    

    输出:

             date  col1  col2  col3  col4
    0  2022/30/01     2     2     4     5
    1  2022/30/01     2     2     4     5
    2  2022/30/01     0     0     1     2
    4  2022/30/01     3     2     4     2
    5  2022/30/01     5     8     4     3
    

    反向操作的替代方案 (eq+all)

    # Is the row duplicated?
    m1 = df.duplicated()
    # Are both cols equal to 0?
    m2 = df[['col1', 'col2']].eq(0).all(1)
    # then keep if not both conditions are met
    df[~(m1&m2)]
    

    【讨论】:

      【解决方案2】:

      您可以通过链 2 条件过滤boolean indexing - 查找没有0 行的行,然后通过DataFrame.duplicated 添加第一个重复的行,默认情况下测试所有列,因为链使用| 按位OR

      df_final = df[df[['col1','col2']].ne(0).all(axis=1) | ~df.duplicated()]
      print (df_final)
               date  col1  col2  col3  col4
      0  2022/30/01     2     2     4     5
      1  2022/30/01     2     2     4     5
      2  2022/30/01     0     0     1     2
      4  2022/30/01     3     2     4     2
      5  2022/30/01     5     8     4     3
      

      细节

      print (df[['col1','col2']].ne(0).all(axis=1))
      0     True
      1     True
      2    False
      3    False
      4     True
      5     True
      dtype: bool
      
      print (~df.duplicated())
      0     True
      1    False
      2     True
      3    False
      4     True
      5     True
      dtype: bool
      

      【讨论】:

      • 我认为您应该使用~df.duplicated(),如果您有超过 2 个重复项,这将保留它们
      【解决方案3】:
      df1.drop(index=df1.query("col1==0 and col2==0")
               .duplicated().loc[lambda x:x].index)
      
            date  col1  col2  col3  col4
      0  2022/30/01     2     2     4     5
      1  2022/30/01     2     2     4     5
      2  2022/30/01     0     0     1     2
      4  2022/30/01     3     2     4     2
      5  2022/30/01     5     8     4     3
      

      【讨论】:

        猜你喜欢
        • 2012-06-05
        • 1970-01-01
        • 2018-09-24
        • 2018-03-05
        • 2021-12-11
        • 1970-01-01
        • 2022-09-28
        • 1970-01-01
        • 2015-11-18
        相关资源
        最近更新 更多