python - 是什么导致 numpy 中 C 有序数组与 F 有序数组沿轴的数组总和不同

标签 python numpy row-major-order column-major-order

我很好奇是否有人可以解释到底是什么导致了 numpy 中 C 与 Fortran 有序数组的特定处理存在差异。请参阅下面的代码:

system:
Ubuntu 18.10
Miniconda python 3.7.1
numpy 1.15.4
def test_array_sum_function(arr):
    idx=0
    val1 = arr[idx, :].sum()
    val2 = arr.sum(axis=(1))[idx]
    print('axis sums:', val1)
    print('          ', val2)
    print('    equal:', val1 == val2)
    print('total sum:', arr.sum())

n = 2_000_000
np.random.seed(42)
rnd = np.random.random(n)

print('Fortran order:')
arrF = np.zeros((2, n), order='F')
arrF[0, :] = rnd
test_array_sum_function(arrF)

print('\nC order:')
arrC = np.zeros((2, n), order='C')
arrC[0, :] = rnd
test_array_sum_function(arrC)

打印:

Fortran order:
axis sums: 999813.1414744433
           999813.1414744079
    equal: False
total sum: 999813.1414744424

C order:
axis sums: 999813.1414744433
           999813.1414744433
    equal: True
total sum: 999813.1414744433

最佳答案

这几乎肯定是 numpy 有时使用 pairwise summation 的结果和 sometimes not .

让我们构建一个诊断数组:

eps = (np.nextafter(1.0, 2)-1.0) / 2
1+eps+eps+eps
# 1.0
(1+eps)+(eps+eps)
# 1.0000000000000002

X = np.full((32, 32), eps)
X[0, 0] = 1
X.sum(0)[0]
# 1.0
X.sum(1)[0]
# 1.000000000000003
X[:, 0].sum()
# 1.000000000000003

这强烈表明一维数组和连续轴使用成对求和,而多维数组中的跨步轴则不使用。

请注意,要看到效果,数组必须足够大,否则 numpy 会退回到普通求和。

关于python - 是什么导致 numpy 中 C 有序数组与 F 有序数组沿轴的数组总和不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55467029/

相关文章:

Python - 在字符串上打印变量

Python 和 OpenCV - 有什么方法可以确保在 cv2.createTrackbar 的轨迹栏上滑动会给我一个奇怪的值?

python - 使用 unstack() reshape pandas 数据框

python - 如何使用matplotlib创建一个原点远离中心且半径大于0的时间螺旋图?

python - Numpy 二维数组,将每行的每个索引剪切到该索引和特定列的最小值

python - 嵌套 np.where

arrays - 在 MATLAB 中,对于二维数组,如何获取首先迭代另一个维度的索引

python - Django 选择选项