Векторизованное решение для получения значения из другой строки в том же фрейме данных

У меня есть фрейм данных, который выглядит так:

Категория Дата Ценить PrevDate1 PrevDate2 А 2022-07-15 4 2022-07-01 2022-07-02 Б 2022-07-16 2 2022-07-08 2022-07-09 Б 2022-07-17 6 2022-07-05 2022-07-16 А 2022-07-18 7 2022-07-10 2022-07-15 А 2022-07-19 9 2022-07-18 2022-07-15

Я хочу добавить столбец, который выбирает значение из другой части фрейма данных. Если PrevDate1 более поздний, чем PrevDate2, он должен вернуть значение, где PrevDate1 равно Date. Или равно PrevDate2, если это более поздняя дата. Каждая дата уникальна, поэтому я должен просто сопоставить предыдущую дату со столбцом даты и получить связанное значение, не обращаясь к категории.

Вывод будет выглядеть следующим образом:

Категория Дата Ценить PrevDate1 PrevDate2 PrevVal А 2022-07-15 4 2022-07-01 2022-07-02 Икс Б 2022-07-16 2 2022-07-08 2022-07-09 Д Б 2022-07-17 6 2022-07-05 2022-07-16 2 А 2022-07-18 7 2022-07-10 2022-07-15 4 А 2022-07-19 9 2022-07-18 2022-07-15 7

Я могу сделать это с помощью цикла, но это медленно, и я продолжаю видеть, что должно быть векторизованное решение для всего в 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 в данной строке.

любезно поделитесь эквивалентом SQL с ожидаемым выходным кадром данных

sammywemmy 11.12.2022 02:53
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пример кода

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

Другие вопросы по теме