добавить новый столбец в фрейм данных с учетом нескольких условий второй фрейм данных - PullRequest
0 голосов
/ 06 мая 2019

Я передаю многозначную лямбда-функцию с помощью метода apply во второй фрейм данных, значения которого, если встречаются с реляционными значениями первого фрейма данных, должны добавить независимый столбец из второго фрейма данных в первый фрейм данных.

В этом случае я бы хотел проверить, совпадает ли автор DF2 с автором DF1, и находится ли дата в DF2 между датами start и end DF1. Если все условия выполнены, то добавьте source к DF1.

Вот мой код. Условия, кажется, проверяются, но среда выполнения, кажется, ставит это под вопрос, поскольку я не получаю никакого вывода вообще.

def add_source(x):
    source_match = master_source.apply(lambda y: y['source'] if
                                                    (y['viewed_date'] >= x['start_date'] 
                                                     and y['viewed_date'] <= x['end_date'] and 
                                                    x['market'] == y['market']) 
                                                    else None, axis=1)
    source_match = source_match.dropna(axis=0, how='all')
    if source_match.empty:
        source_match = np.nan
    else:
        source_match = source_match.to_string(index=False)
    return source_match

1 Ответ

0 голосов
/ 06 мая 2019

Лучшим подходом является создание функции, которую вы будете использовать внутри приложения, например:

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
)

Единственный недостаток этого подхода (который я вижу) - этодубликаты.

...