pandas 如何存储使用“drop_duplicates”删除的行?

Kar*_*ker 3 python dataframe pandas

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

我需要保留从 df 中删除的所有行的日志,但我不确定如何捕获它们。日志应该是一个数据框,我可以为每个.drop.drop_duplicates操作更新它。以下是我想要记录删除行的代码的 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)
Run Code Online (Sandbox Code Playgroud)

我找到了针对不同情况的解决方案,.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.isduplicate相似之处pd.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
Run Code Online (Sandbox Code Playgroud)

然后我实现了 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])
Run Code Online (Sandbox Code Playgroud)

我打印结果:

print(df_keep)
# Output:
       col1      col2 col3
0  whatever  dupe row    x
1     idx 1  uniq row  NaN
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

我想要的是:

print(df_droplog)
# Output:
       col1      col2 col3
2  sth diff  dupe row    x
Run Code Online (Sandbox Code Playgroud)

jpp*_*jpp 5

有一个相似之处: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])
Run Code Online (Sandbox Code Playgroud)