在numpy数组上应用函数会在不同的运行中给出不同的答案

时间:2019-01-10 21:40:57

标签: python numpy

我一直在尝试对我的函数进行矢量化处理,并在代码中遇到了一个我无法弄清的奇怪错误。

这里是有问题的numpy数组(https://filebin.net/c14dcklwakrv1hw8

import numpy as np
example = np.load("example_array.npy") #Shape (2, 5, 5)

我要解决的问题是对每行中的值进行规范化,以使它们的总和为1,当然课程行完全为0。由于numpy除法有一个选项,当我使用的函数除法时,可以跳过0

f = lambda x: np.divide(x, np.sum(x, axis=1)[:, np.newaxis], where=np.sum(x, axis=1)[:, np.newaxis]!=0)

但是,发生的情况是f(example[1])的值发生变化,取决于example[1]example[0]是在它之前的python终端中运行的。因此,如果您运行example[0],然后执行f(example[1]),则example[0]的最后一行将替换答案的第一行。

它的执行可以在这里https://imgur.com/lzyHV8n

Python版本-3.6.6,numpy-1.15.3

编辑:-向矩阵的所有元素加1并重复相同的操作,而在np.divide中没有where条件的情况下工作正常。我想这是错误的根源,但我不知道为什么会发生

1 个答案:

答案 0 :(得分:1)

函数中的问题在于where调用。 numpy.divide()将仅在您的 where 语句被评估为true的位置执行基础ufunc(实际的函数调用在numpy.divide调用中矢量化)。

在其他地方,它会将内存中的所有内容填充到它创建的数组中。为了获得良好的输出,您需要在np.divide函数中使用 out 参数(请参见此处的文档:https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.divide.html)。下面是使用已定义函数的示例实现(您的初始函数也有供参考):

import numpy as np
e = np.load("example_array.npy")

def normalize_badversion(x):
    idx = np.sum(x, axis=1)[:, np.newaxis]
    return np.divide(x, idx, where=idx!=0)

def normalize(x):
    idx = np.sum(x, axis=1)[:, np.newaxis]
    return np.divide(x, idx, where=idx!=0, out=np.zeros_like(x))

print e[0]
a = normalize(e[1])
print e[1]
b = normalize(e[1])
print np.allclose(a,b)


print e[0]
a = normalize_badversion(e[1])
print e[1]
b = normalize_badversion(e[1])
print np.allclose(a,b)

最后说明:我同意当前关于numpy除法的文档在此问题上并不清楚。 numpy文档中推送了一个最新修复程序以澄清这一点,请参见https://github.com/numpy/numpy/commit/9a82c53c8a2b9bd4798e515544de4a701cbfba3f