import pandas as pd

df1 = pd.DataFrame({'id':   [ 1,  1,  1,  2,  2,  2,  3,  3,  3],
                    'nr':   [91, 92, 93, 91, 92, 93, 91, 92, 93],
                    'val_a':[22, 23, 24, 33, 34, 35, 44, 43, 42]})

df2 = pd.DataFrame({'id':   [ 1,  1,  2,  3,  4,  4,  3,  5],
                    'nr':   [91, 92, 91, 99, 92, 93, 92, 99],
                    'val_a':[72, 27, 74, 83, 84, 85, 84, 83]})

def eliminate1 ():
    for i1, row1 in df1.iterrows():
        for i2, row2 in df2.iterrows():
            if row1['id'] == row2['id'] and row1['nr'] == row2['nr']:
                df1.drop(i1, inplace=True)
    df1.reset_index(drop=True, inplace=True)
    print(df1)

eliminate1()

我想删除 df1 中的所有行,其中 'id' AND 'nr' 在 df2 的任何行中具有相等的值。消除1()效果很好,见下面的结果,但在大数据集的情况下非常慢。

这是 df1 和 df2:
   id  nr  val_a
0   1  91     22
1   1  92     23
2   1  93     24
3   2  91     33
4   2  92     34
5   2  93     35
6   3  91     44
7   3  92     43
8   3  93     42

   id  nr  val_a
0   1  91     72
1   1  92     27
2   2  91     74
3   3  99     83
4   4  92     84
5   4  93     85
6   3  92     84
7   5  99     83

这里的结果应该是这样的:
   id  nr  val_a
0   1  93     24
1   2  92     34
2   2  93     35
3   3  91     44
4   3  93     42

有谁知道如何编写更快的代码和/或使用已经存在的函数?

最佳答案

merge

您可以使用 merge 使用 indicator=True 并仅包含标记为 'left_only' 的那些行。

res = df1.merge(df2.drop('val_a', 1), how='left', on=['id', 'nr'], indicator=True)
res = res.loc[res['_merge'] == 'left_only'].drop('_merge', 1)

print(res)

   id  nr  val_a
2   1  93     24
4   2  92     34
5   2  93     35
6   3  91     44
8   3  93     42

该解决方案很容易适应任何条件,具体取决于 'left_only''right_only''both'

关于python - 如果某些行值与第二个 DataFrame 中的行值相同,则有效地从 DataFrame 中删除行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53414888/

10-12 03:06