【问题标题】:Python/Pandas - remove not duplicated rowsPython/Pandas - 删除不重复的行
【发布时间】:2017-11-15 16:03:01
【问题描述】:

我有这样的 DataFrame:

        product_id          dt  stock_qty
226870     2948259  2017-11-11     17.000
233645     2948259  2017-11-12     17.000
240572     2948260  2017-11-13      5.000
247452     2948260  2017-11-14      5.000
233644     2948260  2017-11-12      5.000
226869     2948260  2017-11-11      5.000
247451     2948262  2017-11-14     -2.000
226868     2948262  2017-11-11     -1.000  <- not duplicated
240571     2948262  2017-11-13     -2.000
240570     2948264  2017-11-13      5.488
233643     2948264  2017-11-12      5.488
244543     2948269  2017-11-11      2.500
247450     2948276  2017-11-14      3.250
226867     2948276  2017-11-11      3.250

我必须删除 stock_qty 不同但 product_id 值相同的行。所以我应该得到这样的DataFrame:

        product_id          dt  stock_qty
226870     2948259  2017-11-11     17.000
233645     2948259  2017-11-12     17.000
240572     2948260  2017-11-13      5.000
247452     2948260  2017-11-14      5.000
233644     2948260  2017-11-12      5.000
226869     2948260  2017-11-11      5.000
240570     2948264  2017-11-13      5.488
233643     2948264  2017-11-12      5.488
244543     2948269  2017-11-11      2.500
247450     2948276  2017-11-14      3.250
226867     2948276  2017-11-11      3.250

感谢您的帮助!

【问题讨论】:

    标签: python pandas dataframe data-analysis


    【解决方案1】:

    您需要drop_duplicates 来获取所有product_id 值,然后通过isin 将它们排除在外,另一个条件由xor (^) 链接:

    m1 = df['product_id'].isin(df.drop_duplicates('stock_qty', keep=False)['product_id'])
    m2 = df.duplicated('product_id', keep=False)
    
    df = df[m1 ^ m2]
    print (df)
            product_id          dt  stock_qty
    226870     2948259  2017-11-11     17.000
    233645     2948259  2017-11-12     17.000
    240572     2948260  2017-11-13      5.000
    247452     2948260  2017-11-14      5.000
    233644     2948260  2017-11-12      5.000
    226869     2948260  2017-11-11      5.000
    240570     2948264  2017-11-13      5.488
    233643     2948264  2017-11-12      5.488
    244543     2948269  2017-11-11      2.500
    247450     2948276  2017-11-14      3.250
    226867     2948276  2017-11-11      3.250
    

    详情:

    print (m1)
    226870    False
    233645    False
    240572    False
    247452    False
    233644    False
    226869    False
    247451     True
    226868     True
    240571     True
    240570    False
    233643    False
    244543     True
    247450    False
    226867    False
    Name: product_id, dtype: bool
    
    print (m2)
    226870     True
    233645     True
    240572     True
    247452     True
    233644     True
    226869     True
    247451     True
    226868     True
    240571     True
    240570     True
    233643     True
    244543    False
    247450     True
    226867     True
    dtype: bool
    

    【讨论】:

    • 但是我需要排除 product_id 2948262 的行,因为它们的行与具有相同 product_id 的其他行不重复
    • 如果我有一行具有相同的product_it,此代码也会排除它,但它不应该
    • 我不明白。您可以更改具有所需输出的样本数据吗?或者您认为第三个 product_id 是否是唯一的,例如123 那么这一行要去掉吗?谢谢
    • 我已编辑问题。我添加了 product_id 2948269 的行,它不必删除。
    • 请检查 ;)
    【解决方案2】:

    @jezrael 解决方案是最佳的,但另一种方法是使用groupbyfilter

    df.groupby(['product_id','stock_qty']).filter(lambda x: len(x)>1)
    

    输出:

            product_id          dt  stock_qty
    226870     2948259  2017-11-11     17.000
    233645     2948259  2017-11-12     17.000
    240572     2948260  2017-11-13      5.000
    247452     2948260  2017-11-14      5.000
    233644     2948260  2017-11-12      5.000
    226869     2948260  2017-11-11      5.000
    247451     2948262  2017-11-14     -2.000
    240571     2948262  2017-11-13     -2.000
    240570     2948264  2017-11-13      5.488
    233643     2948264  2017-11-12      5.488
    247450     2948276  2017-11-14      3.250
    226867     2948276  2017-11-11      3.250
    

    【讨论】:

    • 这将删除重复但将保留任何潜在的三次或更多...
    【解决方案3】:

    通过使用drop_duplicates

    df.drop(df.drop_duplicates(['stock_qty', 'product_id'], keep=False).index)
    Out[797]: 
            product_id          dt  stock_qty
    226870     2948259  2017-11-11     17.000
    233645     2948259  2017-11-12     17.000
    240572     2948260  2017-11-13      5.000
    247452     2948260  2017-11-14      5.000
    233644     2948260  2017-11-12      5.000
    226869     2948260  2017-11-11      5.000
    247451     2948262  2017-11-14     -2.000
    240571     2948262  2017-11-13     -2.000
    240570     2948264  2017-11-13      5.488
    233643     2948264  2017-11-12      5.488
    247450     2948276  2017-11-14      3.250
    226867     2948276  2017-11-11      3.250
    

    【讨论】:

      【解决方案4】:

      使用loc[],您可以只过滤重复的行并分配给您的原始数据框。

      df = df.loc[df.duplicated(subset=['product_id','stock_qty'], keep=False)]
      

      同样keep=False 参数将所有重复的行标记为 True,如果您只想要第一个或最后一个使用 keep='first'keep='last'

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-10
        • 2013-02-05
        • 2022-11-14
        • 2021-04-18
        • 1970-01-01
        • 2012-10-09
        • 1970-01-01
        • 2016-05-05
        相关资源
        最近更新 更多