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

У меня есть два кадра данных, master_source и main_df.Я хочу добавить start_date и end_date из main_df в master_source, так как это в конечном итоге позволит мне установить совпадающие индексы на обоих фреймах данных для слияния.

Моя первоначальная логика заключается в проверке 1), совпадает ли market в обоих кадрах данных, и 2), если viewed_date в master_source находится между start_date и end_date в main_df.Если все условия подтвердятся, я хочу добавить start_date и end_date к master_source.

Обратите внимание, что viewed_date, start_date и end_date уже преобразованы в объекты даты и времени.

Вот примеры входных данных для каждого кадра данных:

master_source

viewed_date market
2019-04-15  Abilene, TX
2019-04-11  Yuma, AZ
2019-04-19  Abilene, TX

main_df

market       start_date   end_date
Abilene, TX  2019-04-11   2019-04-17
Yuma, AZ     2019-04-11   2019-04-17
Abilene, TX  2019-04-18   2019-04-26

Мой код:

def add_dates(row):
    matches = main_df[
        (main_df['market'] == row['market']) &
        (row['viewed_date'].between(main_df['start_date'], main_df['end_date']))]
    start = matches['start_date'].values[0] if len(matches) > 0 else None
    end = matches['end_date'].values[0] if len(matches) > 0 else None
    row.loc['start_end', 'end_date'] = start, end
    return row

master_source = master_source.apply(add_dates, axis=1)

Пока что мои известные проблемы - это ошибка AttributeError: ("'Timestamp' object has no attribute 'between'", 'occurred at index 0'), и я не чувствую, что правильно добавляю два новых столбца, а не простоодин новый столбец.

1 Ответ

1 голос
/ 09 мая 2019

Делать это отдельно для начала и окончания работ:

def add_start_dates(market, viewed):
    matches = main_df[(main_df['market'] == market)]

    matches2 = matches[(matches['start_date'] <= viewed)&
                       (matches['end_date'] >= viewed)]
    if len(matches2)>0:
        return matches2['start_date'].iloc[0]
    else:
        return viewed

Аналогично для дат окончания.

print master_source
print 
print main_df
print
master_source['start_date'] = [add_start_dates(m, v) for m, v in zip(master_source['market'],
                                                               master_source['viewed_date'])]
print master_source

выход:

    market viewed_date
0  abilene  2019-04-15
1     yuma  2019-04-11
2  abilene  2019-04-19

    end_date   market start_date
0 2019-04-17  abilene 2019-04-11
1 2019-04-17     yuma 2019-04-11
2 2019-04-26  abilene 2019-04-18


    market viewed_date start_date
0  abilene  2019-04-15 2019-04-11
1     yuma  2019-04-11 2019-04-11
2  abilene  2019-04-19 2019-04-18
...