根据2个ID获得不同的列数据框

时间:2019-06-07 12:09:46

标签: python pandas dataframe

您好,我该如何只对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

1 个答案:

答案 0 :(得分:1)

好吧,这是一个相当复杂的合并,因为您希望在2列上进行合并,并且它们中的任何一个都可以包含应该匹配任何内容(但不能同时匹配两者)的NaN。

我要进行2个单独的合并:

  • id1的F1中id1不是NaN的第一个
  • 秒,其中id1id2的F1中的NaN

在两个结果数据框中,我只会在以下位置保留行:

  • VAL1!= VAL2
  • AND(F1.id2 == F2.id2或F1.id2为NaN或F2.id2为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