【问题标题】:Python/Pandas: Compare multiple columns in two dataframes and remove row if no matches foundPython/Pandas:比较两个数据框中的多列,如果没有找到匹配项,则删除行
【发布时间】:2020-01-16 11:57:30
【问题描述】:

我正在使用 Pandas 学习 Python,并试图找出最有效的方法来比较 2 个数据帧上的多个选定列以找到匹配项。例如,如果我有以下两个数据框:

Frame 1
      A     B    C    D    E    F    
001   10    0    0    10   0    10


Frame 2
      A     B    C    D    E    F
200   10    0    10   0    10   0
201   0     10   10   0    0    10
202   0     10   0    0    0    0
203   0     0    0    10   0    10

我正在寻找一种方法来比较 2 个数据框中的列 ABCD,以便删除任何列中与 10 不匹配的行。

在这种情况下,我希望它删除行 201202 因为没有匹配项,其中行 200203 有 1 个匹配项(即使行 200 有 1 个列不匹配)。

我已经尝试循环遍历第 2 帧中的所有行,比较

letters = ['A', 'B', 'C', 'D']

for ix, row in frame_2():
    for letter in letters:
        if frame_1[letter].values[0] != frame_2.loc[ix, letter]:
            frame_2.drop(ix, inplace=True)
            break

这删除了一些行,但不是全部。

是否有一种有效的方法来遍历所有行并检查另一个数据帧的任何列中是否存在单个匹配项?

提前感谢您的帮助!

【问题讨论】:

  • 嗨,匹配是什么意思?第 2 帧中的行与第 1 帧中的行匹配吗?如果是,0 和 0 不匹配吗?
  • 对不起。我应该更清楚。仅当列值都是 10 时才匹配,因此 0 和 0 不会匹配。
  • 更新了我的问题,希望它更清楚一点

标签: python pandas dataframe


【解决方案1】:

我认为最简单的解决方案是将非10 替换为df1 中的一个值和df2 中的另一个值,将每一列与isin 进行比较,如果df1 有更多行,则可能比较更多值,创建@ 987654326@ DataFrame、concat 并按any 过滤以测试每行至少一个True

letters = ['A', 'B', 'C', 'D']

out = []
for letter in letters:
    m = df2[letter].mask(lambda x: x!=10, 0).isin(df1[letter].mask(lambda x: x!=10, 1))
    out.append(m)

df = df2[pd.concat(out, axis=1).any(axis=1)]

替代解决方案:

df = df2[np.logical_or.reduce(out)]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多