Лучшим подходом является создание функции, которую вы будете использовать внутри приложения, например:
def add_source(row):
matches = df2[
(df2['author'] == row['author']) &
(df2['date'].between(row['start'], row['end']))
]
source = matches['source'].values[0] if len(matches) > 0 else None
row.loc['source'] = source
return row
df1 = df1.apply(add_source, axis=1)
Более упорядоченная логика, как у вас (и более удобочитаемая форма лямбда-функции, которую вы создали).Функция перебирает строку за строкой до df1
, сравнивает конкретные значения из df1
с конкретными значениями в df2
(то есть с теми же значениями author
, чьи значения date
находятся между start
и end
.возвращает первое совпадение (что означает .values[0]
), если есть совпадение (для чего len(matches) > 0
), в противном случае возвращает None
.
Затем присвойте это значение строке какстолбец с именем source
.
Другой подход состоит в том, чтобы просто объединить, а затем просто создать новый столбец, например:
merged_df = pd.merge(
left=df1,
right=df2,
how=left,
on='author'
)
merged_df.loc[:,'new_source'] = merged_df.apply(
lambda row: row['source'] if row['date'].between(row['start'], row['end']),
axis=0
)
Единственный недостаток этого подхода (который я вижу) - этодубликаты.