【问题标题】:pandas How to store rows dropped using `drop_duplicates`?pandas 如何存储使用`drop_duplicates`删除的行?
【发布时间】:2019-06-25 12:09:30
【问题描述】:

注意:请参阅下面的编辑。

我需要记录从我的 df 中删除的所有行,但我不确定如何捕获它们。日志应该是一个数据框,我可以为每个.drop.drop_duplicatesoperation 更新它。以下是我要记录删除行的 3 个代码示例:

df_jobs_by_user = df.drop_duplicates(subset=['owner', 'job_number'], keep='first')
df.drop(df.index[indexes], inplace=True)
df = df.drop(df[df.submission_time.dt.strftime('%Y') != '2018'].index)

我发现this 解决了不同的.drop 案例,该案例使用pd.isnull 重新编码pd.dropna 语句,因此允许在实际删除行之前生成日志:

df.dropna(subset=['col2', 'col3']).equals(df.loc[~pd.isnull(df[['col2', 'col3']]).any(axis=1)])

但在尝试使其适应pd.drop_duplicates 时,我发现没有pd.isduplicatepd.isnull 平行,因此这可能不是达到我需要的结果的最佳方式。


编辑

我在这里重写了我的问题,以便更准确地了解我想要的结果。

我从一个有一个重复行的 df 开始:

import pandas as pd
import numpy as np
df = pd.DataFrame([['whatever', 'dupe row', 'x'], ['idx 1', 'uniq row', np.nan], ['sth diff', 'dupe row', 'x']], columns=['col1', 'col2', 'col3'])
print(df)

# Output:
       col1      col2 col3
0  whatever  dupe row    x
1     idx 1  uniq row  NaN
2  sth diff  dupe row    x

然后我从 jjp 实现解决方案:

df_droplog = pd.DataFrame()
mask = df.duplicated(subset=['col2', 'col3'], keep='first')
df_keep = df.loc[~mask]
df_droplog = df.append(df.loc[mask])

我打印结果:

print(df_keep)
# Output:
       col1      col2 col3
0  whatever  dupe row    x
1     idx 1  uniq row  NaN

df_keep 是我所期望和想要的。

print(df_droplog)
# Output:
       col1      col2 col3
0  whatever  dupe row    x
1     idx 1  uniq row  NaN
2  sth diff  dupe row    x
2  sth diff  dupe row    x

df_droplog 不是我想要的。它包括来自索引 0 和索引 1 的行,这些行没有被删除,因此我不希望在我的删除日志中。它还包括索引 2 中的行两次。我只想要一次。

我想要什么:

print(df_droplog)
# Output:
       col1      col2 col3
2  sth diff  dupe row    x

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    有一个并行:pd.DataFrame.duplicated 返回一个布尔系列。您可以按如下方式使用它:

    df_droplog = pd.DataFrame()
    
    mask = df.duplicated(subset=['owner', 'job_number'], keep='first')
    df_jobs_by_user = df.loc[~mask]
    
    df_droplog = df_droplog.append(df.loc[mask])
    

    【讨论】:

    • 谢谢,但我得到了有趣的结果。我开始使用 3 行 df,2 个骗子。 df_jobs_by_user 很好,但 df_droplog 有 4 行,而不是 1。预期? 0 导入 pd, np 1 df = pd.DataFrame([['a', 'b', np.nan], ['c', 'd', 'a'], ['a', 'b', np.nan]], columns=['col1', 'col2', 'col3']) 2 df_droplog = pd.DataFrame() 3 mask = df.duplicated(subset=['col2', 'col3'], keep='first') 4 df_jobs_by_user = df.loc[~mask] 5 df_droplog = df.append(df.loc[mask]) 6 df_droplog ``` col1 col2 col3 0 ab NaN 1 cda 2 ab NaN 2 ab NaN```跨度>
    • 我编辑了我的原始问题以显示我想要的结果。
    【解决方案2】:

    由于您只需要 df_droplog 中的重复行,因此只需将这些行附加到空数据帧即可。您所做的是将它们附加到原始数据框df。试试这个,

    df_droplog = pd.DataFrame()
    mask = df.duplicated(subset=['col2', 'col3'], keep='first')
    df_keep = df.loc[~mask]
    df_droplog = df_droplog.append(df.loc[mask])
    

    【讨论】:

    • 感谢您发现并告诉我!是的,现在我明白了,现在它可以工作了。非常感谢您不仅告诉我“您正在更新错误的 df”,而且还花时间发布正确的代码。非常有帮助,因为我一直认为问题出在其他地方。
    • @jpp 问题出在df.append。看看他想要什么。据此,解决方案是df_droplog.append
    • @jpp 我不认为这是一个错字。老实说。
    • 将其他人的答案用一个词修复作为单独的帖子重新发布肯定会为您带来积分,但不会让您结交很多朋友。
    • @coldspeed 绝对正确,我也总是避免这样做。这一次,@jpp 的解释是关于函数duplicated,而解决方案是错误的。我没有深入思考,只是回答了它。如果删除我的帖子有帮助,我愿意继续这样做。
    猜你喜欢
    • 1970-01-01
    • 2016-03-21
    • 2021-05-19
    • 2022-01-12
    • 2021-11-07
    • 2016-12-04
    • 1970-01-01
    • 1970-01-01
    • 2017-03-24
    相关资源
    最近更新 更多