我有两个数据帧需要映射并合并成一个。第一个数据框包含NBA球员。标题为“日期”、“球员”、“团队”、“职位”、“工资”、“职位ID”、“分钟”、“FPTS”、“USG”。然后我有第二个数据帧,这是第一个数据帧,但按日期和团队分组。此df的标题为“日期”、“团队”、“分钟”、“FGA”、“FTA”、“To”。我试图计算第一个数据帧中每个播放器的USG速率。要做到这一点,我需要知道在给定的日期,每场比赛中每支球队的总分钟数、射门次数、罚球次数和失误次数。然后,我将同一名球员的数据除以球队的总数据。我有一个可行的解决方案,但它非常缓慢,似乎不是最有效的方法
代码如下:
import pandas as pd
player_df = pd.read_csv('Sample Data') # replace with sample data file
no_dups = player_df.drop_duplicates()
no_dups.loc[:, 'USG'] = pd.Series(dtype=float)
no_dups = no_dups[no_dups.Minutes != 0]
grouped_teams = no_dups.groupby(['Date', 'Team']).agg({'Minutes':['sum'], 'FGA': ['sum'], 'FTA': ['sum'], 'TO': ['sum'] })
grouped_teams.columns = ['Minutes', 'FGA', 'FTA', 'TO']
grouped_teams = grouped_teams.reset_index()
for index, row in no_dups.iterrows():
for i, r in grouped_teams.iterrows():
if no_dups.at[index, 'Team'] == grouped_teams.at[i, 'Team'] and no_dups.at[index, 'Date'] == grouped_teams.at[i, 'Date']:
no_dups.at[index, 'USG'] = (100*((no_dups.at[index, 'FGA'] + 0.44 * no_dups.at[index, 'FTA'] + no_dups.at[index, 'TO'])*(grouped_teams.at[i, 'Minutes']/5))) / (no_dups.at[index, 'Minutes']*(grouped_teams.at[i, 'FGA']+0.44*grouped_teams.at[i, 'FTA']+grouped_teams.at[i, 'TO']))
final_df = no_dups[['Date', 'Player', 'Team', 'Position', 'Salary', 'Minutes', 'FPTS', 'USG']]
print(final_df)
我已经删除了所有没有参加比赛的球员,因为同一个球员可以在一个晚上参加多场比赛,所以我删除了那些球员。然后,我创建了一个名为grouped_teams
的df,它是df中按日期和团队名称分组的每个团队。然后,我使用iterrows
和第二个df以相同的方式迭代第一个df。我需要找到每个球员的球队和具体日期,然后将他的统计数据除以计算出的总数,得到使用率。该列为no_dups.at[index, 'USG']
。在我的df中有73k行,因此遍历每一行需要很长时间
它需要永远,因为您正在逐行迭代。我似乎找不到这篇文章,但我记得在某个地方读过一篇文章,在比较遍历数据帧的方法时,itertuples比iterrows快10倍左右,zip快100倍左右。但是,有时我想从iterrows切换到itertuples时遇到的问题是,您会丢失作为索引的列名,因此您需要特别确保使用itertuples时列的顺序(尽管现在我正在考虑,我认为有一种方法可以动态跟踪)
但最快的方法是对所有行进行计算,而不是逐个进行计算
我要做的是,在第二个数据框中,计算团队总数。因此,在
['Date','Team']
上进行左连接/合并,以匹配no_dups
数据帧上的总数。然后,您可以使用整行列来计算它,而不是一次只计算一行。我还稍微更改了列的名称,好像您合并了,并且有同名的列,它将添加一个后缀_x
和_y
。有办法解决这个问题,但我想直接改变名字。我还稍微改变了列的命名方式,通过不硬编码(这意味着列必须按顺序排列),它可以以更健壮的方式处理名称你还有另一个问题。日期列有不同的格式(即
'1/1/18'
和'2018-01-01'
),因此在您的groupby中,这些格式不会聚合在一起。因此,我们需要首先处理这一问题。它似乎仅适用于Brooklyn网络,但在您的完整数据集中可能会更多代码:
时间:
我对每种方式都进行了计时(不包括在csv中读取的时间)
在样本数据(4493行)上,iError花费了大约
3 minutes 46.66 seconds
。我的代码花了大约
0.0568 seconds
,所以快了将近4000倍相关问题 更多 >
编程相关推荐