熊猫计算特定行和列的滚动总和

时间:2020-10-06 08:04:47

标签: python pandas

我有一个非常具体的问题。

例如,我正在尝试分析一些历史足球数据,并希望为每支球队创建几个专栏,分别提供有关本国和国外的最新进球统计信息。我在这里试图简化事情,假设df看起来像这样:

df = pd.DataFrame({'Home':['A','B','C','B','A','A','C'],'Away':['B','C','A','C','B','B','A'],
                   'HG':[1,2,3,2,1,4,1],'AG':[2,4,5,1,3,2,2]})
  Home Away  HG  AG
0    A    B   1   2
1    B    C   2   4
2    C    A   3   5
3    B    C   2   1
4    A    B   1   3
5    A    B   4   2
6    C    A   1   2

我想做的是为df中的每一行求和最近的两个目标数(HG和/或AG)。但我显然不想考虑最近的行。

因此,如果我们看一下索引行0。Home是'A'。我希望得到的数字是AG下索引行2的6、5,因为A是此行的客队,而索引行4是A是主队,则是6。对于索引行0中的客队B,我希望索引行1和索引行3的结果为4。依此类推。我还想返回np.NaN,如果要计算的少于2个数据点。

我最初想到可能要编写一个小函数来帮助完成此任务,类似于此操作,但显然这是错误的:

def get_rolling_sum(x):
    count_list = []
    new_df = df[(df['Home'] == str(x)) | (df['Away'] == str(x))]
    for i in range(0,len(new_df)):
        if new_df['Home'].iloc[i] == str(x):
            count_list.append(new_df['HG'].iloc[i])
        elif new_df['Away'].iloc[i] == str(x):
            count_list.append(new_df['AG'].iloc[i])
df['Roll_Home'] = [get_rolling_sum(x) for x in df['Home']]

我希望得到的是这样的东西:

  Home Away  HG  AG  Expected_Home
0    A    B   1   2            6.0
1    B    C   2   4            5.0
2    C    A   3   5            2.0
3    B    C   2   1            5.0
4    A    B   1   3            6.0
5    A    B   4   2            NaN
6    C    A   1   2            NaN

非常感谢

1 个答案:

答案 0 :(得分:2)

首先,让我们向数据框添加一列,以使行索引可用。然后创建一个堆叠的数据框,以使Home和Away列成为单个列,而HG和AG列成为单个列,同时保持索引不变。基本上,原始df的Home和Away值将成为两个连续的行。然后从堆栈数据框中获取最近的两行,其参考索引大于原始索引并添加目标。 (您必须手动将最后两行设为NaN。

df = pd.DataFrame({'Home':['A','B','C','B','A','A','C'],'Away':['B','C','A','C','B','B','A'],
               'HG':[1,2,3,2,1,4,1],'AG':[2,4,5,1,3,2,2]})[['Home', 'Away', 'HG', 'AG']]
df['ref_index'] = df.index

df_stack = pd.concat([df[['Home', 'HG']].rename(columns = {'Home':'Loc', 'HG':'Goals'}), 
                  df[['Away', 'AG']].rename(columns = {'Away':'Loc', 'AG':'Goals'})]).sort_index(kind='merge')
df_stack['ref_index'] = df_stack.index

df['Expected_Home'] = df.apply(lambda row: df_stack[(df_stack.Loc == row['Home']) & 
                                                (df_stack.ref_index > row['ref_index'])].iloc[:2].Goals.sum(),
                           axis = 1)

print(df)

     Home   Away    HG  AG  ref_index   Expected_Home
   0    A      B    1   2          0    6
   1    B      C    2   4          1    5
   2    C      A    3   5          2    2
   3    B      C    2   1          3    5
   4    A      B    1   3          4    6
   5    A      B    4   2          5    2
   6    C      A    1   2          6    0