如何根据匹配的年份加上另一个数据帧中的前2年提取多个行

时间:2019-04-16 00:16:41

标签: python pandas dataframe merge

我正在处理体育统计数据,并希望提取过去3年的统计数据。如果我有一个包含播放器和年份的数据框,如何从具有匹配播放器,相同年份和前2个的另一个数据框中提取行?

df1 = pd.DataFrame([['ABC',2018,5,2,3],
['ABC',2017,52,21,31],['ABC',2016,15,12,13],
['ABC',2015,25,22,3]],
columns=['Player','Year','GS','G','MP'])

df1=

Player Year GS G  MP
ABC    2018  5  2  3
ABC    2017 52 21 31
ABC    2016 15 12 13
ABC    2015 25 22 3
df2 = pd.DataFrame([["ABC",2017]], columns=['Player','Year'])

df2=

Player Year
ABC    2017

这应该导致

Player Year GS G  MP
ABC    2017 52 21 31
ABC    2016 15 12 13
ABC    2015 25 22 3

最终,我想进行求和,但是将其提取出来会容易得多。有没有使用合并或过滤器的pythonic方法?

3 个答案:

答案 0 :(得分:0)

merge在“播放器”上,然后过滤以下年份的范围:

res = df1.merge(df2, on='Player', suffixes=['', '_r'])
res = res.loc[res.Year.between(res.Year_r-2, res.Year_r)].drop(columns='Year_r')

print(res)
#  Player  Year  GS   G  MP
#1    ABC  2017  52  21  31
#2    ABC  2016  15  12  13
#3    ABC  2015  25  22   3

或者如果{Player'在df2中没有重复,则映射到一个Series,然后使用布尔系列遮罩:

s = df1.Player.map(df2.set_index('Player').Year)
df1[df1.Year.between(s-2, s)]

#  Player  Year  GS   G  MP
#1    ABC  2017  52  21  31
#2    ABC  2016  15  12  13
#3    ABC  2015  25  22   3

答案 1 :(得分:0)

一个常见的模式是使用df1[df1.Column == value]格式指定要过滤的值。您可以按以下方式组合多个:

years  = [(df2.Year.values[0] - j) for j in range(3)]
player = df2.Player.values[0]
result = df1[(df1.Player == player) & (df1.Year.isin(years))]

答案 2 :(得分:0)

其他答案很好!但这也应该工作:)

# to be safe, at first, sort the DataFrames
df1.sort_index(inplace=True)
df2.sort_index(inplace=True)

# prepare the Masks   Boolean responses
check_1 = df1["Player"] == df2["Player"].to_list()[0]
# to be safe use int() to get integers in the for loop
years_list = (int(df2["Year"].tolist()[0])-i for i in range(0, 3))
check_2 = df1.Year.map(int).isin(years_list)

# apply the masks
print(df1[check_1 & check_2])

无论如何,您不一定需要一个DataFrame来存储匹配的“ Player”和匹配的“ Year”。 两个列表甚至是变量都会更好,因为似乎您没有在df2中设置实际列,就像Erfan在问题下的注释中注意到的那样。