如何比较两个 pandas 数据帧并删除一个文件上的重复项而不附加其他文件中的数据

Phi*_*hes 5 python csv pandas

我正在尝试使用 pandas 数据框比较两个 csv 文件。其中一个是每天都会附加数据的主表 (test_master.csv)。第二个是每日报告 (test_daily.csv),其中包含我想要附加到 test_master.csv 的数据。

我正在从这些文件创建两个 pandas 数据框:

import pandas as pd

dfmaster = pd.read_csv(test_master.csv)
dfdaily = pd.read_csv(test_daily.csv)
Run Code Online (Sandbox Code Playgroud)

我希望将每日列表与主列表进行比较,以查看每日列表上是否存在主列表中已存在的重复行。如果是这样,我希望他们从 dfdaily 中删除重复项。然后我想将这些非重复数据写入 dfmaster。

重复数据将始终是整行。我的计划是逐行迭代工作表以进行比较。

我意识到我可以将每日数据附加到 dfmaster 数据框并使用 drop_duplicates 删除重复项。不过,我不知道如何删除 dfdaily 数据框中的重复项。我需要能够将 dfdaily 数据写回 test_daily.csv (或另一个新文件),而无需重复数据。

这是数据框的示例。

测试_master.csv

  column 1   |  column 2   |  column 3   |
+-------------+-------------+-------------+
| 1           | 2           | 3           |
| 4           | 5           | 6           |
| 7           | 8           | 9           |
| duplicate 1 | duplicate 1 | duplicate 1 |
| duplicate 2 | duplicate 2 | duplicate 2
Run Code Online (Sandbox Code Playgroud)

test_daily.csv

+-------------+-------------+-------------+
|  column 1   |  column 2   |  column 3   |
+-------------+-------------+-------------+
| duplicate 1 | duplicate 1 | duplicate 1 |
| duplicate 2 | duplicate 2 | duplicate 2 |
| 10          | 11          | 12          |
| 13          | 14          | 15          |
+-------------+-------------+-------------+
Run Code Online (Sandbox Code Playgroud)

期望的输出是:

测试_master.csv

+-------------+-------------+-------------+
|  column 1   |  column 2   |  column 3   |
+-------------+-------------+-------------+
| 1           | 2           | 3           |
| 4           | 5           | 6           |
| 7           | 8           | 9           |
| duplicate 1 | duplicate 1 | duplicate 1 |
| duplicate 2 | duplicate 2 | duplicate 2 |
| 10          | 11          | 12          |
| 13          | 14          | 15          |
+-------------+-------------+-------------+
Run Code Online (Sandbox Code Playgroud)

test_daily.csv

+----------+----------+----------+
| column 1 | column 2 | column 3 |
+----------+----------+----------+
|       10 |       11 |       12 |
|       13 |       14 |       15 |
+----------+----------+----------+
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激!

编辑

我错误地认为集合差异问题的解决方案解决了我的问题。我遇到过这些解决方案不起作用的某些情况。我相信这与下面 Troy D 的评论中提到的索引数字标签有关。Troy D 的解决方案就是我现在使用的解决方案。

Tro*_*y D 4

尝试这个:

我创建了 2 个索引,然后将第 2-4 行设置为重复:

import numpy as np

test_master = pd.DataFrame(np.random.rand(3, 3), columns=['A', 'B', 'C'])
test_daily = pd.DataFrame(np.random.rand(5, 3), columns=['A', 'B', 'C'])
test_daily.iloc[1:4] = test_master[:3].values

print(test_master)
print(test_daily)
Run Code Online (Sandbox Code Playgroud)

输出:

      A         B         C
0  0.009322  0.330057  0.082956
1  0.197500  0.010593  0.356774
2  0.147410  0.697779  0.421207
      A         B         C
0  0.643062  0.335643  0.215443
1  0.009322  0.330057  0.082956
2  0.197500  0.010593  0.356774
3  0.147410  0.697779  0.421207
4  0.973867  0.873358  0.502973
Run Code Online (Sandbox Code Playgroud)

然后,添加多索引级别来标识哪些数据来自哪个数据帧:

test_master['master'] = 'master'
test_master.set_index('master', append=True, inplace=True)
test_daily['daily'] = 'daily'
test_daily.set_index('daily', append=True, inplace=True)
Run Code Online (Sandbox Code Playgroud)

现在按照您的建议合并并删除重复项:

merged = test_master.append(test_daily)
merged = merged.drop_duplicates().sort_index()
print(merged)
Run Code Online (Sandbox Code Playgroud)

输出:

             A         B         C
  master                              
0 daily   0.643062  0.335643  0.215443
  master  0.009322  0.330057  0.082956
1 master  0.197500  0.010593  0.356774
2 master  0.147410  0.697779  0.421207
4 daily   0.973867  0.873358  0.502973
Run Code Online (Sandbox Code Playgroud)

在那里您可以看到组合数据框以及索引中标记的数据来源。现在只需对每日数据进行切片:

idx = pd.IndexSlice
print(merged.loc[idx[:, 'daily'], :])
Run Code Online (Sandbox Code Playgroud)

输出:

             A         B         C
  master                              
0 daily   0.643062  0.335643  0.215443
4 daily   0.973867  0.873358  0.502973
Run Code Online (Sandbox Code Playgroud)