【问题标题】:Why does computing mean with numpy.mean(A, axis=1)[0] differs from computing mean with numpy.mean(A[0,:])?为什么用 numpy.mean(A, axis=1)[0] 计算平均值与用 numpy.mean(A[0,:]) 计算平均值不同?
【发布时间】:2021-12-05 13:08:36
【问题描述】:

我得到了二维数组 A 和 B。它们是相同的,但是通过两种不同的方法获得。考虑以下几行:

In  [1]: (A==B).all()
Out [1]: True
In  [2]: A.shape
Out [2]: (500, 10805)
In  [3]: B.shape
Out [3]: (500, 10805)
In  [4]: numpy.mean(A,axis=1)[0]
Out [4]: -0.006108739586784807
In  [5]: numpy.mean(A[0,:])
Out [5]: -0.006108739586784786
In  [6]: numpy.mean(B,axis=1)[0]
Out [6]: -0.006108739586784786
In  [7]: numpy.mean(B[0,:])
Out [7]: -0.006108739586784786

如您所见,第 [4] 行的结果与第 [5]、[6] 和 [7] 行的结果不同,但它们应该相同。这是什么原因?

numpy.sum() 和 numpy.std() 也会出现同样的问题。

【问题讨论】:

  • 可能是浮动算术精度
  • 最有可能 numpy.mean 执行多线程操作 (OpenMP) 并且归约操作不是确定性的。在浮动操作中,A+B+C 不一定严格等于 A+C+B。如果您认为这是一个问题,您可以在启动您的 python 代码之前尝试将 KMP_DETERMINISTIC_REDUCTION=TRUE 设置为全局环境变量。
  • 输出是否具有确定性,即重新执行第 4 行是否总是得到相同“错误”结果?
  • @DaniMesejo 你可能是对的。但是 A 和 B 怎么可能相等但不会产生相同的“错误”结果呢?即 numpy.mean(A,axis=1)[0] != numpy.mean(B,axis=1)[0]

标签: python numpy


【解决方案1】:

你正在做数值运算。他们预计不会 100% 准确。例如。严格来说,数值加法不是关联的。 IE。这取决于添加的顺序。考虑这个例子

(1e-20+1.0)-1.0 -> 0
1e-20+(1.0-1.0) -> 1e-20

现在,如果数据在内存中进行排序,以便以不同的顺序对其进行汇总更快,您可能会得到略有不同的结果。

在这里我转置(沿对角线镜像),复制数据并将其转置回来,所以我知道它必须相等但得到不同的方法。

np.random.seed(20881)
A = np.random.random((100,100))
B = A.T.copy().T
(A==B).all() --> True
B.mean()-A.mean() -> 3.3306690738754696e-16

注意np.random.random((100,100)) 通常是随机的,但在np.random.seed(20881) 之后总是返回相同的数组。选择数字/数组,即使是 100 x 100 数组也会给您带来与您的更大数组一样大的错误。

【讨论】:

  • 感谢您的回答。您的帖子可以解释为什么 A 和 B 的手段之间存在差异;实际上,在我的程序中,我有一个原始矩阵 A,我通过一系列转置将其扩充到矩阵 B。但是,我认为您的帖子没有回答以下问题:为什么在计算第一列的平均值没有差异时,通过行 [4] 和 [5] 计算 A 的第一列的平均值存在差异B 列通过第 [6] 行和 [7] 行?
  • @Háski 如果您提供了 A 和 B 中的数字以及 np.info(A),np.info(B) 的结果,会更容易判断。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 2017-01-06
  • 2012-06-19
  • 2020-07-15
相关资源
最近更新 更多