数组的列求和 - 两种方法,两种不同的结果

Columnwise sum of array - two methods, two different results

在此示例中,数组 pr 的列式总和以两种不同的方式计算:

(a) 使用 p.sumaxis 参数

在第一个轴上求和

(b) 沿第二个轴对数组进行切片并取每个切片的总和

import matplotlib.pyplot as plt
import numpy as np


m = 100
n = 2000
x = np.random.random_sample((m, n))

X = np.abs(np.fft.rfft(x)).T
frq = np.fft.rfftfreq(n)

total = X.sum(axis=0)
c = frq @ X / total

df = frq[:, None] - c
pr = df * X


a = np.sum(pr, axis=0)
b = [np.sum(pr[:, i]) for i in range(m)]

fig, ax = plt.subplots(1)
ax.plot(a)
ax.plot(b)
plt.show()

这两种方法应该 return 相同,但出于某种原因,在本例中,它们并不相同。正如您在下图中看到的,ab 具有完全不同的值。然而,差异是如此之小以至于 np.allclose(a, b) 为真。

如果把pr换成一些小的随机值,两种求和方式没有区别:

pr = np.random.randn(n, m) / 1e12
a = np.sum(pr, axis=0)
b = np.array([np.sum(pr[:, i]) for i in range(m)])

fig, ax = plt.subplots(1)
ax.plot(a)
ax.plot(b)
plt.show()

第二个例子说明第一个例子求和的不同与求和方法无关。那么,这是一个与浮点值求和有关的问题吗?如果是这样,为什么在第二个例子中没有出现这样的效果?

为什么第一个例子中的按列求和不同,哪个是正确的?

为什么结果不同,请参阅。切片情况使用成对求和,轴情况不。

哪个是正确的?嗯,可能两者都不是,但预计成对求和会更准确。

事实上,我们可以看到它非常接近使用 math.fsum 获得的准确(在机器精度内)结果。