我正在处理体育统计数据,并希望提取过去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方法?
答案 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在问题下的注释中注意到的那样。