如何在 Python 中更快地计算中位数
How to make the calculation of the median faster in Python
我想在超过 500,000 行的数据框中逐行计算中值。目前我使用 np.median
因为 numpy 在单核上优化为 运行。它仍然很慢,我想找到一种并行计算的方法
具体来说,我有 N
table 大小 13 x 500,000
并且对于每个 table 我想添加列 Q1、Q3 和中位数,以便每个row the median 列包含行的中位数。所以我必须计算 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]
编辑 2 我通过使用下面提出的中值算法的中值解决了我的问题
由@dahhiya_boy
提供
您可以使用 statistics
模块中的 median()
import statistics
statistics.median(items)
你可以用median()
和min()
的中位数计算Q1,你可以用median()
和max()
的中位数计算Q3。如果你觉得这很乱,只需定义一个 quartile_median()
函数,即 returns Q1,Q2,Q3
据我了解,您想逐行计算分位数。
您可以简单地转置您的数据框,然后应用 pandas.DataFrame.quantile
你不确定这是不是最优的。
q=data.quantile([0.25,0.50,0.75],axis=0)
如果您有 IPython 活动,您可以使用行魔法:%time
在该行之前检查 运行 时间。
%time
q=data.quantile([0.25,0.50,0.75],axis=0)
这个returns:对我来说Wall time: 0 ns
。
如果中位数的(接近)近似值适合您的目的,您应该考虑计算中位数的中位数,这是一种可以执行的分而治之策略在平行下。原则上,MoM 对于串行执行具有 O(n)
的复杂性,在大规模并行系统上接近 O(1)
的并行执行。
有关 GPU 实现,请参阅 this Wiki entry for a description and pseudo-code. See also this question on Stack Overflow and discussion of the code, and this ArXiv paper。
我想在超过 500,000 行的数据框中逐行计算中值。目前我使用 np.median
因为 numpy 在单核上优化为 运行。它仍然很慢,我想找到一种并行计算的方法
具体来说,我有 N
table 大小 13 x 500,000
并且对于每个 table 我想添加列 Q1、Q3 和中位数,以便每个row the median 列包含行的中位数。所以我必须计算 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]
编辑 2 我通过使用下面提出的中值算法的中值解决了我的问题
由@dahhiya_boy
提供您可以使用 statistics
模块中的 median()
import statistics
statistics.median(items)
你可以用median()
和min()
的中位数计算Q1,你可以用median()
和max()
的中位数计算Q3。如果你觉得这很乱,只需定义一个 quartile_median()
函数,即 returns Q1,Q2,Q3
据我了解,您想逐行计算分位数。
您可以简单地转置您的数据框,然后应用 pandas.DataFrame.quantile
你不确定这是不是最优的。
q=data.quantile([0.25,0.50,0.75],axis=0)
如果您有 IPython 活动,您可以使用行魔法:%time
在该行之前检查 运行 时间。
%time
q=data.quantile([0.25,0.50,0.75],axis=0)
这个returns:对我来说Wall time: 0 ns
。
如果中位数的(接近)近似值适合您的目的,您应该考虑计算中位数的中位数,这是一种可以执行的分而治之策略在平行下。原则上,MoM 对于串行执行具有 O(n)
的复杂性,在大规模并行系统上接近 O(1)
的并行执行。
有关 GPU 实现,请参阅 this Wiki entry for a description and pseudo-code. See also this question on Stack Overflow and discussion of the code, and this ArXiv paper。