我有一个非常具体的问题。
例如,我正在尝试分析一些历史足球数据,并希望为每支球队创建几个专栏,分别提供有关本国和国外的最新进球统计信息。我在这里试图简化事情,假设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
非常感谢
答案 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