我正在尝试遍历大量试验并计算多个子集的加权平均值。目前,数据为长格式,其中包含列试用版,区域得分。
trial area score
0 T106 0 0.0035435
1 T106 1 0.0015967
2 T106 4 0.0003191
3 T106 4 0.1272919
4 T288 0 0.1272883
我有大约120,000个试验,有4个区域,每个试验可能有10到100个分数,总共约700万行。我的第一个想法是在4个区域内循环遍历所有试验,构建一个临时数据框以计算分数,然后将分数添加到外部数据框:
for area in range(4):
for trial in trial_names.iloc[:,0]:
Tscore = 0
temp_trial = pd.DataFrame(trials_long.loc[(trials_long['tname'] == trial) & (trials_long['area'] == int(area))])
#match score in tria
temp_trial = temp_trial.merge(scores_df, how='left')
#sum score for all matching 'trial' +'area' #this will be weigted avrg, with >0.5 *2 and >0.9* 3
temp_trial.loc[temp_trial['score'] > 0.9, ['score']] *= 3 #weight 3x for >0.9
temp_trial.loc[temp_trial['score'] > 0.5, ['score']] *= 2 #weight 2x for >0.5
Tscore = temp_trial['score'].sum() / int(len(temp_trial.index))
trial_names.loc[trial,area] = Tscore #store Tscore somewhere
Tscore = 0
print('done')
此解决方案在一个4.0 GHz线程上花费10分钟以上的时间。在这种情况下,时间实际上是至关重要的,计算需要在15秒左右的时间内完成。在R中,我通常会使用许多矢量化函数来跳过循环,而我做过的任何循环都将在多个内核上并行进行,但是在python中,我并不熟悉最佳方法。我也愿意学习一些新的东西,也许是哈希图?
谢谢!
答案 0 :(得分:5)
这是我尝试过的:
df['weighted'] = df['score']
df.loc[df['score']>.9, 'weighted'] *= 3
df.loc[df['score']>.5, 'weighted'] *= 2
# s is indexed by ('trial', 'area')
s = df.groupby(['trial', 'area']).weighted.mean()
花费1.16秒来处理6600k上的700万行。