Python 分配给numpy数组的值并不总是等于分配的值
以下过程产生的值并不总是与指定的值匹配:Python 分配给numpy数组的值并不总是等于分配的值,python,numpy,scipy,Python,Numpy,Scipy,以下过程产生的值并不总是与指定的值匹配: from scipy.interpolate import splprep, splev, splrep import numpy as np pos2indx = lambda vec: vec.round().astype(np.int64) t = np.linspace(1,3,150) x = 150+100*np.sin(t) + 5*np.random.randn(len(t)) y = 150+100*np.cos(t) + 5*np
from scipy.interpolate import splprep, splev, splrep
import numpy as np
pos2indx = lambda vec: vec.round().astype(np.int64)
t = np.linspace(1,3,150)
x = 150+100*np.sin(t) + 5*np.random.randn(len(t))
y = 150+100*np.cos(t) + 5*np.random.randn(len(t))
z = 150+100*np.cos(t)*np.sin(t) + 5*np.random.randn(len(t))
vector_field = np.zeros((x.max()+10,y.max()+10,z.max()+10,3), dtype=np.float64)
out = splprep([x,y,z],u=t,k=3, full_output=1, quiet=1)
tck, t = out[0]
v = np.transpose(splev(t,tck, der=1))
i,j,k = pos2indx(x),pos2indx(y),pos2indx(z)
vector_field[i,j,k,:] += v
print np.sum(np.abs(vector_field[i,j,k,:]-v))
我希望这个过程总是打印零。
然而,有时它不是!
当输出为非零时,则为数千
我不确定我是做错了什么,还是这里有什么漏洞
我也把这当作一个棘手的问题来报道
解决方案:
Pauli Virtanen:“错误就在你的代码中:i,j,k向量可以包含给定的坐标对两次。”()
jorgeca在下面给出了类似的答案
谢谢 这个问题似乎是由舍入误差引起的 我使用数据类型对代码
1000次进行了比较:float16
、float32
、float64
和float96
;在向量_字段中
并计算给出非零答案的次数:
float16: 1000
float32: 1000
float64: 142
float96: 115
总结您的问题,将v
添加到零数组,然后减去v
并不总是生成零数组:
vector_field = np.zeros((x.max()+10,y.max()+10,z.max()+10,3), dtype=np.float64)
vector_field[i,j,k,:] += v
print np.sum(np.abs(vector_field[i,j,k,:]-v)) # sometimes not 0!!
那不可能是对的
事实上,索引i
、j
和k
都是numpy数组,因此它正在使用。当重复三组索引时会发生什么?也就是说,对于一些m,当i[m]==i[n]
、j[m]==j[n]
和k[m]==k[n]
时。结果是,通过一个(可以随时更改)只分配索引的最后三元组(按C顺序),如果将v
(使用dtype np.float64)存储在一个不同的dtype数组中,vector_字段[i,j,k:]
实际上并不包含v,您将失去精度,因此当将其与原始的v
(仍然是np.float64)进行比较时,它们在大多数情况下都不相等(即,float64(float32(64位\u数))!=64位\u数)。尝试更改v
的数据类型,任何数据类型都会有100-150个差异,因此这不是实际原因。您是正确的,重复索引(由于卷的离散化)是原因。我回到这一页是为了发表我在SciPy issues post上收到的相同答案(由Pauli Virtanen回答):“错误在你的代码中:I,j,k向量可以多次包含给定的坐标三元组。”啊,因为你写了报告,我在回答之前搜索了github中的问题列表,但不知何故错过了已经关闭的问题列表。。。这不是一个好主意,交叉张贴,所以一般来说,我会首先问这里,如果它被证明是一个错误,然后报告它。不过,很高兴你把问题解决了。我接受你关于交叉帖子的评论。事实上,我几乎可以肯定这是一个错误,我犹豫是否张贴在这里所有。。。再次感谢您的评论!