Я думаю, вам нужно numpy.where
, если одинаковая длина и одинаковые значения индекса в обоих кадрах данных при сравнении обоих столбцов с DataFrame.all
:
df1['d'] = np.where((df1[['a', 'b']] == df2[['a', 'b']]).all(axis=1), df2['d'], df1['d'])
print (df1)
a b c d
0 1 2 5 2
1 1 5 5 1
2 2 3 4 4
print (df1[['a', 'b']] == df2[['a', 'b']])
a b
0 True True
1 True False
2 True True
print ((df1[['a', 'b']] == df2[['a', 'b']]).all(axis=1))
0 True
1 False
2 True
dtype: bool
Еще одно более общее решение для сопоставления по merge
с левым соединением, но необходимы уникальные строки в df2
по столбцам a
и b
по drop_duplicates
, последний combine_first
и удалите ненужный столбец d_
:
df = (df1.merge(df2.drop_duplicates(['a','b']), on=['a','b'], how='left', suffixes=('_',''))
.assign(d= lambda x: x['d'].combine_first(x['d_']))
.drop('d_', axis=1))
print (df)
a b c d
0 1 2 5 2.0
1 1 5 5 1.0
2 2 3 4 4.0
print (df2.drop_duplicates(['a','b']))
a b d
0 1 2 2
2 2 3 4
print (df1.merge(df2.drop_duplicates(['a','b']), on=['a','b'], how='left', suffixes=('_','')))
a b c d_ d
0 1 2 5 1 2.0
1 1 5 5 1 NaN
2 2 3 4 1 4.0