我有一个形状为 2500, 200 的 2-D Numpy 数组,其中 Scipy 用于计算数组中每个条目的统计数据(特别是伽玛 CDF)。我为那些旨在本地运行代码的人提供了随机生成的浮点数,请注意,该数组中的数据必须表示为小数。代码如下:
def gcdfstats(inputarr):
if all(x==inputarr[0] for x in inputarr):
value = 0
else:
param = sci.stats.gamma.fit(inputarr)
x = np.linspace(0, int(np.round(np.max(inputarr), 0)), int(np.round(np.divide(np.max(inputarr), 0.01), 0)))
cdf = sci.stats.gamma.cdf(x, *param)
value = np.round((sci.stats.gamma.cdf(1.25, *param) * 100), 2)
return value
def getrow_stats():
# Generate A Random Sample of Numbers (2,500 Entries, 200 Values Each) in Float Precision
inputarr = np.random.uniform(0.00, 8.00, (2500,200))
# Compute Gamma CDF For Each
outstats = [gcdfstats(entry) for entry in inputarr]
return outstats
在整个阵列上运行此命令后,我注意到在每个阵列条目上计算这些统计数据的速度低于标准。在服务器上总共运行 5 次后,我平均每秒完成 7-10 个条目/CDF 值,这对于较大的数据集来说太慢了。
尽管没有可以立即在整个数组中广播的特定 Numpy 函数,但我仍然采取了特定步骤来确保 gcdfstats 函数快速运行。这包括在适当的情况下使用列表理解来代替 for 循环和 Numpy ufunc(max、divide 和 round)。
是否可以采取任何额外步骤来加快此功能的完成?
stats.gamma.cdf
速度相当快。代码中的时间片段显示 stats.gamma.fit
主导了执行时间:
import numpy as np
from scipy import stats
inputarr = np.random.uniform(0.00, 8.00, (200))
%timeit stats.gamma.fit(inputarr)
# 44.3 ms ± 2.82 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
param = stats.gamma.fit(inputarr)
x = np.linspace(0, int(np.round(np.max(inputarr), 0)), int(np.round(np.divide(np.max(inputarr), 0.01), 0)))
%timeit stats.gamma.cdf(x, *param)
# 206 µs ± 22.9 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
cdf = stats.gamma.cdf(x, *param)
%timeit np.round((stats.gamma.cdf(1.25, *param) * 100), 2)
# 136 µs ± 17.5 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
这是因为当分布位置自由时,
stats.gamma.fit
依赖于通用优化例程来执行最大似然估计。通常,伽马分布在没有位置参数的情况下使用(例如Wikipedia)。如果这适合您的用例,您可以将位置固定为零,并且fit
会更快。
%timeit stats.gamma.fit(inputarr, floc=0)
# 90.6 µs ± 54 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)