У меня есть фрейм данных, который выглядит так:
Я хочу добавить столбец, который выбирает значение из другой части фрейма данных. Если PrevDate1 более поздний, чем PrevDate2, он должен вернуть значение, где PrevDate1 равно Date. Или равно PrevDate2, если это более поздняя дата. Каждая дата уникальна, поэтому я должен просто сопоставить предыдущую дату со столбцом даты и получить связанное значение, не обращаясь к категории.
Вывод будет выглядеть следующим образом:
Я могу сделать это с помощью цикла, но это медленно, и я продолжаю видеть, что должно быть векторизованное решение для всего в pandas. Я пробовал варианты:
df['PrevVal'] = np.where(df['PrevDate1'] > df['PrevDate2'], df['Value'][df['Date'] == df['PrevDate1'], df['Value'][df['Date'] == df['PrevDate2'])
Но это не работает, и я понимаю, почему это не сработает. Я искал python-эквивалент коррелированного подзапроса в SQL, но ничего не смог найти.
Код SQL выглядит примерно так:
update table set PrevVal = (select case when PrevDate1 > PrevDate2
then (select Value from table where Date = tb.PrevDate1))
from table tb
Это говорит ему искать Date во всей таблице для PrevDate1 в данной строке.
Пример кода
data = {'Category': {0: 'A', 1: 'B', 2: 'B', 3: 'A', 4: 'A'},
'Date': {0: '2022-07-15', 1: '2022-07-16', 2: '2022-07-17', 3: '2022-07-18', 4: '2022-07-19'},
'Value': {0: 4, 1: 2, 2: 6, 3: 7, 4: 9},
'PrevDate1': {0: '2022-07-01', 1: '2022-07-08', 2: '2022-07-05', 3: '2022-07-10', 4: '2022-07-18'},
'PrevDate2': {0: '2022-07-02', 1: '2022-07-09', 2: '2022-07-16', 3: '2022-07-15', 4: '2022-07-15'}}
df = pd.DataFrame(data)
Процесс
сделать маппер(это серия) для маппинга
mapper = df['Value'].set_axis(df['Date'])
mapper
Date
2022-07-15 4
2022-07-16 2
2022-07-17 6
2022-07-18 7
2022-07-19 9
Name: Value, dtype: int64
отображение картографом на максимальную (самую последнюю) предыдущую дату
df[['PrevDate1', 'PrevDate2']].max(axis=1).map(mapper)
результат:
0 NaN
1 NaN
2 2.0
3 4.0
4 7.0
Name: PrevDate2, dtype: float64
сделать результат столбцом PrevVal
Полный код и вывод
mapper = df['Value'].set_axis(df['Date'])
df.assign(PrevVal=df[['PrevDate1', 'PrevDate2']].max(axis=1).map(mapper))
выход:
Category Date Value PrevDate1 PrevDate2 PrevVal
0 A 2022-07-15 4 2022-07-01 2022-07-02 NaN
1 B 2022-07-16 2 2022-07-08 2022-07-09 NaN
2 B 2022-07-17 6 2022-07-05 2022-07-16 2.0
3 A 2022-07-18 7 2022-07-10 2022-07-15 4.0
4 A 2022-07-19 9 2022-07-18 2022-07-15 7.0
Если вам нужно отличаться для каждой категории, используйте merge
вместо map
любезно поделитесь эквивалентом SQL с ожидаемым выходным кадром данных