Я тестирую симуляцию на лайтерах, таким образом, что я ожидаю, что калоудация на заданную дату вернет такое же число, независимо от датеранга который я рассчитываю для данной партии.Nump, pandas, Matlab, R несоответствие суммарной суммы, с разной продолжительностью истории
То есть, если я позвоню системе для диапазона 1990-2000, то результат 1995.07.01 должен быть таким же, как при вызове системы на 1995-1996 годы. Должно быть достаточно базовым, я подумал ...
Проблема в том, что быстрые свертывающие окна реализуют ошибки округления, которые зависят от длины истории за пределами окна качения. Поэтому, когда я делаю 20-дневную скользящую сумму за 1995.07.01, результат будет иметь большую скопированную ошибку округления в случае запуска операции сальниковой суммы на тайм-сервере с 1990 года.
Вот пример, где я ожидал бы не-нан результаты точно соответствовать:
df = pd.DataFrame([xrange(7)]).astype('float64').T
df = np.sqrt(df)
roll1_df = pd.rolling_sum(df, window=3)
roll2_df = pd.rolling_sum(df.iloc[3:, :], window=3)
но я получаю ошибку округления:
roll1_df - roll2_df
0
0 NaN
1 NaN
2 NaN
3 NaN
4 NaN
5 8.881784e-16
6 1.776357e-15
пример использует Python/панд, но проблема та же в любой номер хруст программного обеспечения, поэтому я рад за идеи, в пандах, numpy, Matlab, R ... или bas по чистой теории.
Было бы важно сохранить преимущество производительности операций быстрой прокатки, т. Е. Избегать простого суммирования последних значений N для всех дат (что будет в O (N) раза медленнее, чем более быстрые версии развертывания качения).
Edit: Решение
Я выбрал следующее решение в конце концов, принимая панда друг от друга и положить обратно вместе с небольшим количеством округления в rolling_sum:
rolling_sum_stable_df = _rolling_func(
lambda *arg_l: np.round(roll_sum(*arg_l), decimals=11),
'Stable rolling_sum'
)
удалось преобразовать в float32 первого перед тем rolling_sum(), а затем конвертировать обратно в float64, но затем потеряет больше цифр. Недостатком подхода является то, что я должен сделать это для roll_cov и других функций качения, которые немного больше задействованы.
Я не совсем уверен, что понимаю, что именно вы суммируете. Но если вы хотите точное равенство между двумя результатами, то число чисел с плавающей запятой никогда не сделает вас счастливыми. Вам придется либо использовать целые типы, либо реализовать «почти равные», а не «равные». – sebastian
Вы можете использовать ['np.isclose'] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.isclose.html):' np.isclose (roll1_df [3:], roll2_df) 'Это показывает, что последние 2 значения достаточно близки, чтобы считаться равными. – EdChum
Пробовал это несколько лет назад. К сожалению, числовые ошибки нелинейны в системе, т. Е. Разница 1е-16 может вызвать большие изменения в более поздних числах. –