Вот альтернативный подход, который распространяется на многие типы безопасности (CUSIP, ISIN, RI C, SEDOL, и т. Д. c.).
Сначала создайте df1
и df2
по строкам исходного примера:
import numpy as np
import pandas as pd
df1 = pd.DataFrame({'sec_id': [11, 22, 33],
'sec_id_type': ['CUSIP', 'ISIN', 'RIC'],
'value': [100, 200, 300]})
df2 = pd.DataFrame({'CUSIP': [11, 21, 31],
'ISIN': [21, 22, 23],
'RIC': [31, 32, 33],
'SEDOL': [41, 42, 43]})
Во-вторых, создайте промежуточный фрейм данных x1
. Мы будем использовать первый столбец для одного соединения, а второй и третий столбцы для другого соединения:
index = [idx for idx in df2.index for _ in df2.columns]
sec_id_types = df2.columns.to_list() * df2.shape[0]
sec_ids = df2.values.ravel()
data = [
(idx, sec_id_type, sec_id)
for idx, sec_id_type, sec_id in zip(index, sec_id_types, sec_ids)
]
x1 = pd.DataFrame.from_records(data, columns=['index', 'sec_id_type', 'sec_id'])
Join df1
и x1
для извлечения значений из df1
:
x2 = (x1.merge(df1, on=['sec_id_type', 'sec_id'], how='left')
.dropna()
.set_index('index'))
Наконец, объедините df2
и x1
(из предыдущего шага), чтобы получить окончательный результат
print(df2.merge(x2, left_index=True, right_index=True, how='left'))
CUSIP ISIN RIC SEDOL sec_id_type sec_id value
0 11 21 31 41 CUSIP 11 100.0
1 21 22 32 42 ISIN 22 200.0
2 31 23 33 43 RIC 33 300.0
Столбцы sec_id_type
и sec_id
показывают, что объединения работают должным образом.