【发布时间】:2019-01-30 18:54:35
【问题描述】:
我喜欢对具有许多已知信号形状的数据(一个 numpy 浮点数组)进行最小二乘匹配。我的代码可以运行,但对于我计划进行的多次运行来说太慢了:
import numpy
import time
samples = 50000
width_signal = 100
data = numpy.random.normal(0, 1, samples)
signal = numpy.random.normal(0, 1, width_signal) # Placeholder
t0 = time.clock()
for i in range(samples - width_signal):
data_chunk = data[i:i + width_signal]
residuals = data_chunk - signal
squared_residuals = residuals**2
summed_residuals = numpy.sum(squared_residuals)
t1 = time.clock()
print('Time elapsed (sec)', t1-t0)
编辑:更正了一个错误:先将残差平方,然后将它们相加。
在我的机器上运行大约需要 0.2 秒。由于我有很多数据集和信号形状,这太慢了。我的具体问题不允许使用典型的 MCMC 方法,因为信号形状差异太大。它必须是蛮力。
典型的数据量为 50,000 个浮点数,信号为 100 个浮点数。这些值可能相差几倍。
我的测试表明:
- 数据的总和
numpy.sum(residuals)占用了 90% 的时间。我尝试了 Python 的sum(residuals),它对于小数组(~if 条件吗? - 我试过
numpy.roll()而不是直接取数据,.roll()比较慢。
问题:
- 对于加速有逻辑上的改进吗?
- 有没有更快的方法来对数组求和?我不会 C,但如果它更快,我可以试试。
- GPU 可以提供帮助吗?我有很多跑步要做。如果是这样,我在哪里可以找到代码 sn-p 来执行此操作?
【问题讨论】:
-
您可能对
pandas.rolling有一些运气,但随后创建 DF 的开销可能会开始占主导地位 -
您是否考虑过使用卷积而不是平方差之和?另外,平方必须在总和内吗?
-
啊,当然,我犯了一个错误:必须先对残差求平方,然后再对这些平方残差求和。我在 Q 中更改了它。是否可以使用 np.lib.stride_tricks.as_strided 执行此操作?非常感谢。
-
应该是
for i in range(samples - width_signal + 1):覆盖所有。 -
关于 +1 的长度:在实践中,我将不得不翻过边缘。真实数据是相位折叠的,因此信号可以在数据末尾附近开始并在开头继续。
标签: python arrays performance numpy