答案 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]