如何使用 Pandas 进行条件 VLOOKUP,使用两列作为 VLOOKUP 的索引?

How to use Pandas to do a conditional VLOOKUP using two columns as an index for the VLOOKUP?

我是 Pandas 和 Python 的新手,我根本不知道如何做一些在 Excel 中很容易完成的事情。我希望能从社区得到一些帮助。

假设我有以下内容,这是一个与梦幻足球相关的 df,它具有三列 - 'Name'、'Year' 和 '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],
                   })

我想在 table 中添加另一个名为 'FantasyPtsPreviousYear' 的列,但在 Pandas / Python 中很难弄清楚如何这样做。

我想做的是:

  1. 对于 table 中的每一行,让 python / pandas 检查 df 该行中的名称和年份。
  2. 查找同一玩家在上一年(即Year - 1)获得的梦幻积分
  3. 在名为 'FantasyPtsPreviousYear' 的 df 的新行中填充该数字,或者,如果没有该球员前一年的数据,请输入 0。

在 Excel 中,我将简单地创建新列并将这些列与 VLOOKUP 一起使用。我在 Pandas 中找到的与 VLOOKUP 最接近的东西是合并,但这似乎在这里不起作用(或者至少我不知道如何让它与这个特定的应用程序一起工作)。在尝试找到答案后,我认为它可能与 loc() 函数和 For 循环有关,但我无法使其工作。

感谢您提供的任何帮助!我非常感谢,并认为这个社区提供的所有帮助都很棒!

我相信这可以通过 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

让我们尝试 groupbyshift

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

merge DataFrame 本身,您在其中将年份加 1。这明确定义了 Year -> Year-1 每个玩家的比赛

(小心 shift,除非你 确定 你每年都有一行。没有明确地重新索引所有年份 shift group 会给出你有数据的最后一年,不管那是 1 年前还是 10 年前(如果缺少数据))


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