使用python pandas检查两列之间的数据匹配和不匹配

时间:2019-03-11 09:26:34

标签: python pandas

下面的示例数据

enter image description here

给出了文件A和文件B的

输入,还给出了输出格式。有人可以帮我吗

2 个答案:

答案 0 :(得分:0)

我也很好奇看到一个聪明的/ pythonic解决方案。我遍历索引的“丑陋”解决方案如下:

dfa,dfb是两个数据帧,列均按示例命名。

dfa, dfb = dfa.set_index(['c1','c2']), dfb.set_index(['c1','c2'])
mismatch3, mismatch4 = [],[]
for i in dfa.index:
    if i in dfb.index:
        if dfa.loc[i,'c3']!=dfb.loc[i,'c3']:
            mismatch3.append(i)
        if dfa.loc[i,'c4']!=dfb.loc[i,'c4']:
            mismatch4.append(i)
mismatch = list(set(mismatch3+mismatch4))

现在让我们创建索引列表,以识别dfa和dfb之间不匹配的行

dfb = dfb.rename(index=str, columns={'c3':'b_c3','c4':'b_c4'})
df = dfa.loc[mismatch].join(dfb)

df['c3_status'] = 'match'
df['c4_status'] = 'match'
df.loc[mismatch3, 'c3_status'] = 'mismatch'
df.loc[mismatch4, 'c4_status'] = 'mismatch'

现在完成了,我们想重命名dfb,对不匹配的索引执行联接操作,并基于mismatch3和mismatch4添加“状态”列。

result = df[['c3','b_c3','c3_status','c4','b_c4','c4_status']] 

最后,让我们以正确的顺序获取这些列:)

{{1}}

再一次,我希望看到一个更漂亮的解决方案。我希望这会有所帮助!

答案 1 :(得分:0)

这是四行代码,它们可以满足您的需求:

ListPackageGallery

解释

假设您要查看 c2 c3 列中 dfa 中没有的 dfb 行。

  • 为此,请考虑以下方法:

dfa 中创建一列“ Combo”,其中“ Combo”的每一行都包含一个逗号分隔的字符串,表示要比较的所选列的值(针对相关行)

columns_to_compare =['c2','c3']
dfa['Combo'] = dfa[columns_to_compare].apply(lambda x: ', '.join(x[x.notnull()]), axis = 1)
dfb['Combo1'] = dfb[columns_to_compare].apply(lambda x: ', '.join(x[x.notnull()]), axis = 1)
[i for i,x in enumerate(dfb['Combo1'].tolist()) if x not in dfa['Combo'].tolist()] 

dfb

应用相同的逻辑
dfa['Combo'] = dfa[dfa.columns].apply(lambda x: ', '.join(x[x.notnull()]), axis = 1)

    c1  c2  c3   c4     Combo
0   v   100 tech hhh    100, tech
1   f   110 jjj  scb    110, jjj
2   h   235 None kkk    235
3   m   999 iii  lop    999, iii
4   s   333 mnp  sos    333, mnp
5   d   39  lf   kdk    39, lf

创建一个包含dfb所需索引的列表:

    c1  c2  c3   c4     Combo1
0   v   100 tech hhh    100, tech
1   h   235 None mckkk  235
2   m   999 iii  lok    999, iii
3   f   110 jkl  scb    110, jkl
4   L   777 9kdf ooo    777, 9kdf
5   s   333 mnp1 sos1   333, mnp1

或显示实际的行值(不是索引):

[i for i,x in enumerate(dfb['Combo1'].tolist()) if x not in dfa['Combo'].tolist()] 

行索引结果

[[x] for i,x in enumerate(dfb['Combo1'].tolist()) if x not in dfa['Combo'].tolist()]  

增值结果

[3, 4, 5]