Столбчатая сумма массива - два метода, два разных результата - PullRequest
2 голосов
/ 02 апреля 2019

В этом примере сумма столбцов для массива pr вычисляется двумя различными способами:

(a) взять сумму по первой оси, используя p.sum 'axisпараметр

(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()

Оба метода должны возвращать одно и то же, но по какой-либо причине, в этом примере,они не.Как вы можете видеть на графике ниже, a и b имеют совершенно разные значения.Разница, однако, настолько мала, что np.allclose(a, b) - это Истина.

imagea and 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()

imagea and b set with random values">

Второй пример показывает, что различия в суммах первого примера не связаны сметоды суммирования.Тогда эта проблема связана с суммированием значений с плавающей запятой?Если так, то почему такой эффект не возникает во втором примере?

Почему суммы по столбцам отличаются в первом примере и какой из них правильный?

1 Ответ

4 голосов
/ 02 апреля 2019

Почему результаты отличаются, см. https://stackoverflow.com/a/55469395/7207392. В случае среза используется парное суммирование, в случае с осью - нет.

Какой из них верный?Ну, вероятно, нет, но парное суммирование, как ожидается, будет более точным.

Действительно, мы можем видеть, что оно довольно близко к точному (с точностью до машины) результату, полученному с использованием math.fsum.

enter image description here

...