【问题标题】:How to do extract multiple rows based on matching year plus 2 previous years from another dataframe如何根据匹配年份加上前两年从另一个数据框中提取多行
【发布时间】:2019-09-06 00:10:40
【问题描述】:

我正在处理体育统计数据,并希望提取过去 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 方式来做到这一点?

【问题讨论】:

  • 我没有看到从df2 中提取的任何列。你最终的目标是什么。 df2 中还有更多数据吗?
  • 对列求和,然后用结果更新 2018 行。对于在 df2 中有匹配的玩家和年份的所有 df1 都需要执行此操作(df2 有更多数据,如果不明显,请见谅)

标签: python pandas dataframe merge


【解决方案1】:

merge on 'Player' 然后过滤之后的年份范围:

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

或者如果“玩家”在df2 中没有重复,则映射到一个系列,然后使用布尔系列进行掩码:

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

【讨论】:

    【解决方案2】:

    一种常见的模式是使用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))]
    

    【讨论】:

      【解决方案3】:

      其他答案都不错!但这也应该有效:)

      # 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 在您的问题下的评论中注意到的那样。

      【讨论】:

        猜你喜欢
        • 2021-12-16
        • 1970-01-01
        • 2019-06-25
        • 1970-01-01
        • 1970-01-01
        • 2018-04-17
        • 1970-01-01
        • 2017-06-14
        • 2020-11-21
        相关资源
        最近更新 更多