如何使用 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 中很难弄清楚如何这样做。
我想做的是:
- 对于 table 中的每一行,让 python / pandas 检查 df 该行中的名称和年份。
- 查找同一玩家在上一年(即Year - 1)获得的梦幻积分
- 在名为 '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
让我们尝试 groupby
和 shift
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
我是 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 中很难弄清楚如何这样做。
我想做的是:
- 对于 table 中的每一行,让 python / pandas 检查 df 该行中的名称和年份。
- 查找同一玩家在上一年(即Year - 1)获得的梦幻积分
- 在名为 '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
让我们尝试 groupby
和 shift
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