【问题标题】:How to make the calculation of the median faster in Python如何在 Python 中更快地计算中位数
【发布时间】:2019-08-16 14:55:04
【问题描述】:

我想在超过 500,000 行的数据框中逐行计算中位数。目前我正在使用np.median,因为 numpy 已经过优化,可以在单核上运行。它仍然很慢,我想找到一种并行计算的方法

具体来说,我有 N 大小为 13 x 500,000 的表,并且对于每个表,我想添加列 Q1、Q3 和中值,以便每一行的中值列包含该行的中值。所以我必须计算N * 500,000 中值。

我尝试使用numexpr,但似乎不可能。

编辑: 事实上,我还需要 Q1 和 Q3,所以我不能使用不允许计算四分位数的统计模块。这是我目前计算中位数的方法

    q = np.transpose(np.percentile(data[row_array], [25,50,75], axis = 1))
    data['Q1_' + family] = q[:,0]
    data['MEDIAN_' + family] = q[:,1]
    data['Q3_' + family] = q[:,2]

EDIT 2我通过使用下面提出的中位数算法的中位数解决了我的问题

【问题讨论】:

  • 你试过这个吗? import statistics statistics.median(items)
  • 看问题的编辑部分,谢谢你的回答
  • Q1 是最低值的中位数和数据集的中位数,可以这样计算。
  • 好吧,我不知道,但我认为从计算时间的角度来看,像这样一次计算 3 仍然更有趣。事实上,为了加快计算速度,我正在考虑并行化操作,但我不知道该怎么做
  • 它总是有 3 列吗?

标签: python multithreading numpy median


【解决方案1】:

如果中位数的(接近)近似值适合您的目的,您应该考虑计算中位数的中位数,这是一种可以并行执行的分而治之的策略。原则上,MoM 的串行执行复杂度为O(n),在大规模并行系统上的并行执行复杂度接近O(1)

有关描述和伪代码,请参阅 this Wiki entry。另请参阅 this question on Stack Overflow 和代码讨论,以及 this ArXiv paper 了解 GPU 实现。

【讨论】:

    【解决方案2】:

    感谢@dahhiya_boy

    您可以使用statistics 模块中的median()

    import statistics
    
    statistics.median(items)
    

    你可以用median()min()的中位数计算Q1,你可以用median()max()的中位数计算Q3。如果你觉得这很乱,只需定义一个返回 Q1,Q2,Q3 的 quartile_median() 函数

    【讨论】:

    • 看问题的编辑部分,谢谢你的回答
    • 这就是@dahhiya_boy 的建议,但正如我在回答中所说,我认为它在计算时间方面效率不高。 (如果我错了,请纠正我)
    • 我不是这方面的专家,但我很确定四分位数函数无论如何都是这样计算四分位数的。四分位数的定义是中位数和极值的中位数,我认为没有更快的方法来计算它
    • 您是完全正确的,但是要计算中位数,您必须对表进行排序,使用 numpy 表排序一次,使用统计模块有 3 个函数调用,因此表排序 3 次。这就是为什么我认为它实际上会减慢程序的速度。
    • 这是一个好点,但考虑到sort() 时间是 nlog2(n),这应该不是太大的问题
    【解决方案3】:

    据我了解,您希望逐行计算分位数。 您可以简单地转置您的数据框,然后应用 pandas.DataFrame.quantile 不确定这是最佳选择。

    q=data.quantile([0.25,0.50,0.75],axis=0)
    

    如果你激活了 IPython,你可以在行前使用 line magic: %time 来检查运行时间。

    %time
    q=data.quantile([0.25,0.50,0.75],axis=0)
    

    这会返回:Wall time: 0 ns 给我。

    【讨论】:

    • 很有趣,我看看能不能节省一些计算时间
    • 已测试,更好但不是很明显
    • 我相信转置数据帧会导致大幅放缓。你能用探查器检查一下吗?
    • 我的意思是如果你可以检查每个函数花费的计算时间并向我们展示结果
    • @PierreCarceller 检查更新的答案。您实际上可以指定要在哪个轴上计算分位数 =)。这应该会大大加快计算速度。
    猜你喜欢
    • 2011-12-12
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 2018-07-08
    • 2014-05-20
    相关资源
    最近更新 更多