【问题标题】:Fast averaging over Pandas dataframe subsetsPandas 数据帧子集的快速平均
【发布时间】:2019-09-01 13:47:51
【问题描述】:

我正在尝试循环大量试验并计算多个子集的加权平均值。目前数据为长格式,列试验、面积分数。

  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 中,我不熟悉最好的方法。我也愿意学习一些新的东西,也许是哈希图?

谢谢!

【问题讨论】:

  • 乍一看,我觉得您可以在区域和试验中使用 pandas groupby,然后 apply 对每个子集使用自定义函数来检查您的阈值/计算加权平均值。这将至少为您节省其中一个 for 循环,但如果您可以在函数内对代码进行矢量化,则可能两者兼而有之
  • 也许使用df.apply 在一次运行中将多个df.loc 替换为udf 会有所帮助。 groupby 这两列也不错!

标签: python pandas


【解决方案1】:

这是我尝试过的:

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()

在 6600k 上处理 700 万行需要 1.16 秒。

【讨论】:

  • 这是一个优雅而有效的解决方案。谢谢!
猜你喜欢
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 2010-11-01
  • 2020-05-31
  • 2019-04-15
相关资源
最近更新 更多