设置 numpy 数组的列值的奇怪结果

meT*_*sky 2 python numpy numpy-slicing numpy-ndarray

在下面的脚本中,我想将旋转矩阵应用于(Nx3)数组的前两列。

rotate_mat = lambda theta: np.array([[np.cos(theta),-np.sin(theta)],[np.sin(theta),np.cos(theta)]])

rot_mat = rotate_mat(np.deg2rad(90))

basis1 = np.array([[i+1,j+1,k+1] for k in range(3) for j in range(3) for i in range(3)])
basis2 = basis1.copy()
rot = basis2[:,0:2] @ rot_mat

print('rot','\n',rot[:3],'\n')
print('basis2','\n',basis2[:3],'\n')

basis2[:,0:2] = rot
print('basis2 after','\n',basis2[:3])
Run Code Online (Sandbox Code Playgroud)

运行此脚本后,我获得了此输出

rot 
 [[ 1. -1.]
 [ 1. -2.]
 [ 1. -3.]] 

basis2 
 [[1 1 1]
 [2 1 1]
 [3 1 1]] 

basis2 after 
 [[ 1  0  1]
 [ 1 -2  1]
 [ 1 -3  1]]
Run Code Online (Sandbox Code Playgroud)

正如你所看到的basis2[:,0:2] = rot,第一行basis2[1,0,1],但是,第一行rot显然是[1,-1],这0是从哪里来的?

fla*_*awr 5

如果你看一下你的条目,rot你会发现它rot[0,1]-0.9999999999999999. 此外basis2.dtype == dtype('int32')。因此,在分配期间,新条目将转换为将int32它们四舍五入为零。你可以验证

np.int32(rot[0, 1]) == 0
Run Code Online (Sandbox Code Playgroud)

np.int32(rot[0, 1] - 1e-16) == -1
Run Code Online (Sandbox Code Playgroud)

这是由于四舍五入,因为np.cos(np.deg2rad(90)) == 6.123233995736766e-17当您可能期望它恰好为 0 时。