首页 > 解决方案 > 为什么 np.add.at() 对大型数组返回错误的答案?

问题描述

我有一个大数据集 ,statisticstatistic.shape = (1E10,)想有效地将​​(总和)合并到一个零数组中,out = np.zeros(1E10)。中的每个条目statistic都有一个对应的索引 ,idx它告诉我out它属于哪个 bin。索引不是唯一的,所以我不能使用out += statistic[idx],因为这只会计算第一次遇到特定索引的时间。因此我使用np.add.at(out, idx, statistic). 我的问题是,对于非常大的数组, np.add.at() 返回错误的答案。

下面是显示此行为的示例脚本。该函数check_add()应返回 1。

import numpy as np

def check_add(N):
    N = int(N)
    out = np.zeros(N)
    np.add.at(out, np.arange(N), np.ones(N))
    return np.sum(out)/N

n_arr = [1E3, 1E5, 1E8, 1E10]
for n in n_arr:
    print('N = {} (log(N) = {}); output ratio is {}'.format(n, np.log10(n), check_add(n)))

这个例子为我返回:

N = 1000.0 (log(N) = 3.0); output ratio is 1.0
N = 100000.0 (log(N) = 5.0); output ratio is 1.0
N = 100000000.0 (log(N) = 8.0); output ratio is 1.0
N = 10000000000.0 (log(N) = 10.0); output ratio is 0.1410065408

有人可以向我解释为什么该功能会失败N=1E10吗?

标签: pythonnumpy

解决方案


这是一个老错误,NumPy 问题 13286ufunc.at为循环计数器使用了一个太小的变量。它不久前得到了修复,所以更新你的 NumPy。(该修复程序存在于 1.16.3 及更高版本中。)


推荐阅读