您好,我该如何只对2个数据帧中val不同的行进行处理。
我需要过滤的方式如下:
对于F1的每一行(如果每个id1不为null,则获取每个id1来搜索id1 F2),比较VAL,如果它不同则返回VAL。否则请看id2并做同样的事情。
请注意,我可以拥有id1或id2或两者都有,如下所示:
d2 = {'id1': ['X22', 'X13',np.nan,'X02','X14'],'id2': ['Y1','Y2','Y3','Y4',np.nan],'VAL1':[1,0,2,3,0]}
F1 = pd.DataFrame(data=d2)
d2 = {'id1': ['X02', 'X13',np.nan,'X22','X14'],'id2': ['Y4','Y2','Y3','Y1','Y22'],'VAL2':[1,0,4,3,1]}
F2 = pd.DataFrame(data=d2)
F1在哪里
id1 id2 VAL1
0 X22 Y1 1
1 X13 Y2 0
2 NaN Y3 2
3 X02 Y4 3
4 X14 NaN 0
F2为:
id1 id2 VAL2
0 X02 Y4 1
1 X13 Y2 0
2 NaN Y3 4
3 X22 Y1 3
4 X14 Y22 1
预期输出:
d2 = {'id1': ['X02',np.nan,'X22','X14'],'id2': ['Y4','Y3','Y1',np.nan],'VAL1':[3,2,1,0],'VAL2':[1,4,3,1]}
F3 = pd.DataFrame(data=d2)
id1 id2 VAL1 VAL2
0 X02 Y4 3 1
1 NaN Y3 2 4
2 X22 Y1 1 3
3 X14 NaN 0 1
答案 0 :(得分:1)
好吧,这是一个相当复杂的合并,因为您希望在2列上进行合并,并且它们中的任何一个都可以包含应该匹配任何内容(但不能同时匹配两者)的NaN。
我要进行2个单独的合并:
id1
的F1中id1
不是NaN的第一个id1
是id2
的F1中的NaN 在两个结果数据框中,我只会在以下位置保留行:
然后我会吸引他们。代码可能是:
t = F1.loc[~F1['id1'].isna()].merge(F2, on=['id1']).query('VAL1!=VAL2')
t = t[(t.id2_x==t.id2_y)|t.id2_x.isna()|t.id2_y.isna()]
t2 = F1.loc[F1['id1'].isna()].merge(F2, on=['id2']).query('VAL1!=VAL2')
t2 = t2[(t2.id1_x==t2.id1_y)|t2.id1_x.isna()|t2.id1_y.isna()]
# build back lost columns
t['id2'] = np.where(t['id2_x'].isna(), t['id2_y'], t['id2_x'])
t2['id1'] = np.where(t2['id1_x'].isna(), t2['id1_y'], t2['id1_x'])
# concat and reorder the columns
resul = pd.concat([t.drop(columns=['id2_x', 'id2_y']),
t2.drop(columns=['id1_x', 'id1_y'])],
ignore_index=True, sort=True).reindex(columns=
['id1', 'id2', 'VAL1', 'VAL2'])
结果是:
id1 id2 VAL1 VAL2
0 X22 Y1 1 3
1 X02 Y4 3 1
2 X14 Y22 0 1
3 NaN Y3 2 4