【问题标题】:Compare dataframe columns with conditions将数据框列与条件进行比较
【发布时间】:2018-11-21 23:54:01
【问题描述】:

我有 2 个数据框如下:

df1:

ID   col1   col2    
1     A1     B1    
2     A2     B2     
3     A3     B3   
4     A4     B4   
5     A5     B5    
6     A6     B6    

df2:

col1   col2   
 A1     B1     
 A2     O5   
 H3     B3     
 A4     B4    
 A5     66     
 A6     C6     

预期结果:我想根据条件生成结果 df - df1 的 col1、col2 中的每个值都应该存在于 df2 的 col1、col2 值中

预期结果df:

ID   col1   col2     Error
1     A1     B1      No mismatch with df2
2     A2     B2      col2 mismatch with df2
3     A3     B3      col1 mismatch with df2
4     A4     B4      No mismatch with df2
5     A5     B5      col2 mismatch with df2
6     A6     B6      col2 mismatch with df2

【问题讨论】:

  • 您在 df2 中没有列表
  • list 是 df1 中的一列,它的值 list1 和 list2 只是下拉列表名称;接受的值在 df2 的 list1、list2 列中给出。因此,应使用 df2 list1 & list2 值检查 df1 的“值”列中基于其列表值的数据。
  • 编辑问题

标签: python pandas dataframe


【解决方案1】:

创建具有字典理解的辅助 DataFrame 并与 isin 进行比较:

m = pd.DataFrame({c: ~df1[c].isin(df2[c]) for c in ['col1','col2']})
print (m)
    col1   col2
0  False  False
1  False   True
2   True  False
3  False  False
4  False   True
5  False   True

然后numpy.where 用any 掩码测试每行至少一个True 和dot 用矩阵乘法来获取列名:

df1['Error'] = np.where(m.any(axis=1), 
                        m.dot(m.columns + ', ').str.rstrip(', ') + ' mismatch with df2', 
                       'No mismatch with df2')
print (df1)
   ID col1 col2                   Error
0   1   A1   B1    No mismatch with df2
1   2   A2   B2  col2 mismatch with df2
2   3   A3   B3  col1 mismatch with df2
3   4   A4   B4    No mismatch with df2
4   5   A5   B5  col2 mismatch with df2
5   6   A6   B6  col2 mismatch with df2

【讨论】:

  • m = pd.DataFrame({c: ~df1[c].isin(df2[c]) for c in ['col1','col2']}) - col1 和 col2 很难-编码。当我尝试使用 df.cols 直接从数据框中传递列名时,它会显示以下错误“ValueError: Must pass DataFrame with boolean values only”-对此有何帮助?
  • 如果我像这样传递数据框中的所有列,代码应该可以工作 lovcols = df2.columns m = pd.DataFrame({c: ~dfCSDataset[c].isin(dfLOVRules[c]) for c in [lovcols]}
  • @Osceria - 是的,你是对的。您还可以将列传递给字典理解,例如 m = pd.DataFrame({c: ~df1[c].isin(df2[c]) for c in df2.columns})
【解决方案2】:

这样的事情应该可以解决问题,但可能有更简单的方法。

diff = pd.concat([df1[col] == df2[col] for col in df1], axis=1)

def m(row):
    mismatches = []
    for col in diff.columns:
        if not row[col]:
            mismatches.append(col)
    if mismatches == []:
        return 'No mismatch'
    return 'Mismatches: ' + ', '.join(mismatches)

df1['Error'] = diff.apply(m, axis=1)

【讨论】:

  • 当我尝试这个时,我得到错误“ValueError: Can only compare same-labeled Series objects”
  • 编辑问题
  • @Osceria 您是否会在以下可重现的数据集上遇到相同的错误:df1 = pd.DataFrame({'col1': ["A1", "A2", "A3", "A4", "A5", "A6"], 'col2': ["B1", "B2", "B3", "B4", "B5", "B6"]}) df2 = pd.DataFrame({'col1': ["A1", "A2", "H3", "A4", "A5", "A6"], 'col2': ["B1", "O5", "B3", "B4", "66", "C6"]})
  • 这是因为你的df1 和df2 有不同的列,对吧?我注意到您现在编辑了问题,它是否适用于这些数据框?
  • 如果我运行我用上面的数据框回答的内容,它似乎可以工作。
猜你喜欢
  • 2018-07-25
  • 2022-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-14
相关资源
最近更新 更多