我看到ufunc where
的{{1}}子句有奇怪的行为。
Numpy 1.15.3
似乎我只能使用In [1]: import numpy as np
In [2]: x = np.array([[1,2],[3,4]])
In [3]: y = np.ones(x.shape) * 2
In [4]: print(x, "\n", y)
[[1 2]
[3 4]]
[[2. 2.]
[2. 2.]]
In [5]: np.add(x, y, where=x==3)
Out[5]:
array([[2., 2.], #<=========== where do these 2s come from???
[5., 2.]])
In [6]: np.add(x, y, where=x==3, out=np.zeros(x.shape))
Out[6]:
array([[0., 0.],
[5., 0.]])
In [7]: np.add(x, y, where=x==3, out=np.ones(x.shape))
Out[7]:
array([[1., 1.],
[5., 1.]])
In [8]: np.add(x, y, where=x==3)
Out[8]:
array([[1., 1.], # <========= it seems these 1s are remembered from last computation.
[5., 1.]])
参数来获得合理的结果。
以下没有out
参数:
out
这会产生一个荒谬的图像:
如果我按如下所示添加import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = np.linspace(-2,2,60)
y = np.linspace(-2,2,60)
xx, yy = np.meshgrid(x,y)
r= np.ones((60,60), dtype=float) * 2
z = np.sqrt(r**2 - xx**2 - yy**2, where=(r**2 - xx**2 - yy**2)>=0) # <==== HERE!!
surf = ax.plot_surface(xx, yy, z, cmap="viridis")
参数,则一切正常。
out
答案 0 :(得分:3)
由于使用where
,您最终在输出中得到了垃圾数据。如您所说,解决方法是初始化自己的输出并将其传递给out
。
如果'out'为None(默认值),则会创建一个未初始化的返回数组。然后,在广播“ where”为True的地方,用ufunc的结果填充输出数组。如果“ where”是标量True(默认值),则它对应于要填充的整个输出。请注意,未明确填充的输出将保留其未初始化的值。
因此,您跳过的out
的值(即where
是False
的索引)将保留之前的值。这就是为什么numpy
会“保留”先前计算的值,例如第一个示例代码块末尾的1
。
正如@WarrenWeckesser在其评论中指出的那样,这也意味着至少在某些情况下,out
留为空白时,将同一存储块重新用于输出。有趣的是,您可以通过将每个输出分配给变量来更改获得的结果:
x = np.array([[1,2],[3,4]])
y = np.ones(x.shape) * 2
arr0 = np.add(x, y, where=x==3)
arr1 = np.add(x, y, where=x==3, out=np.zeros(x.shape))
arr2 = np.add(x, y, where=x==3, out=np.ones(x.shape))
arr3 = np.add(x, y, where=x==3)
print(arr3)
现在您可以清楚地在输出中看到垃圾数据:
[[-2.68156159e+154 -2.68156159e+154]
[ 5.00000000e+000 2.82470645e-309]]