Как использовать Pandas для выполнения условной ВПР с использованием двух столбцов в качестве индекса для ВПР? - PullRequest
3 голосов
/ 13 июля 2020

Я новичок в Pandas и Python, и я просто не могу понять, как сделать то, что очень легко сделать в Excel. Я надеялся получить небольшую помощь от сообщества.

Предположим, у меня есть следующая информация о фэнтези-футболе с тремя столбцами - «Имя», «Год» и «FantasyPts». . Код ниже.

import pandas as pd

df = pd.DataFrame({'Name': ['Tom Brady', 'Tom Brady', 'Tom Brady', 'Patrick Mahomes', 'Patrick Mahomes', 'Patrick Mahomes'],
                   'Year': [2019, 2018, 2017, 2019, 2018, 2017],
                   'FantasyPts': [300, 350, 400, 500, 400, 50],
                   })

Я хочу добавить в таблицу еще один столбец под названием «FantasyPtsPreviousYear», но мне очень сложно понять, как это сделать в Pandas / Python.

Я хочу сделать следующее:

  1. Для каждой строки таблицы python / pandas проверьте имя и год в этой строке df.
  2. Найдите количество очков фэнтези, набранных тем же игроком в предыдущем году (например, Год - 1)
  3. Заполните это число в новой строке df под названием 'FantasyPtsPreviousYear' или, если нет данных для предыдущего года для этого игрока введите 0.

В Excel я бы просто создал новые столбцы и использовал бы эти столбцы с ВПР. Самая близкая вещь, которую мне удалось найти для VLOOKUP в Pandas, - это слияние, но это, похоже, здесь не работает (или, по крайней мере, я не могу понять, как заставить его работать с этим конкретным приложением c). После попытки найти ответ, я думаю, что это может иметь какое-то отношение к функции lo c () и For l oop, но я не могу заставить его работать.

Спасибо за любая помощь, которую вы можете предоставить! Я очень ценю это и считаю, что это сообщество великолепно за всю ту помощь, которую оно предоставляет!

Ответы [ 3 ]

3 голосов
/ 13 июля 2020

Давайте попробуем groupby с shift

df = df.sort_values(['Name','Year'],ascending=[True,True])
df['FantasyPtsPreviousYear'] = df['FantasyPts'].groupby(df['Name']).shift().fillna(0)
3 голосов
/ 13 июля 2020

Я считаю, что этого можно достичь с помощью комбинации where() и shift(). Однако для этого необходимо предварительно отсортировать данные. Вот код с учетом предоставленных вами данных:

df = df.sort_values(['Name','Year'],ascending=[True,True])
df['FantasyPtsPreviousYear'] = df['FantasyPts'].shift().where(df['Name'].eq(df['Name'].shift())).fillna(0)
print(df)

Это выводит:

              Name  Year  FantasyPts  FantasyPtsPreviousYear
5  Patrick Mahomes  2017          50                     0.0
4  Patrick Mahomes  2018         400                    50.0
3  Patrick Mahomes  2019         500                   400.0
2        Tom Brady  2017         400                     0.0
1        Tom Brady  2018         350                   400.0
0        Tom Brady  2019         300                   350.0
2 голосов
/ 13 июля 2020

merge DataFrame с самим собой, где вы добавляете 1 к году. Это явно определяет соответствие Год -> Год-1 для каждого игрока

(будьте осторожны с shift, если только вы не уверены, что у вас есть строка для каждого года. Без явной переиндексации для всех лет a shift внутри группы даст вам последний год, за который у вас есть данные, независимо от того, 1 год a go или 10 лет a go (если данные отсутствуют))

df = df.merge((df.assign(Year=df['Year']+1)
                 .rename(columns={'FantasyPts': 'FantasyPts_prev'})), 
              how='left', on=['Name', 'Year'])
df['FantasyPts_prev'] = df['FantasyPts_prev'].fillna(0, downcast='infer')

              Name  Year  FantasyPts  FantasyPts_prev
0        Tom Brady  2019         300              350
1        Tom Brady  2018         350              400
2        Tom Brady  2017         400                0
3  Patrick Mahomes  2019         500              400
4  Patrick Mahomes  2018         400               50
5  Patrick Mahomes  2017          50                0
...