鉴于以下代码,我希望最后两行表现相同,但不要。
import numpy as np
C = np.matrix(np.zeros((4,4)))
C[0, 0:2] = np.matrix([[1, 2]]) # Works as expected.
C[0, [0,1]] = np.matrix([[1, 2]]) # Throws an "array is not broadcastable to correct shape" error.
使用ndarray
代替时,事情按预期工作(将分配的右侧调整为一维ndarray
):
D = np.zeros((4,4))
D[0, 0:2] = np.array([1, 2]) # Works as expected.
D[0, [0,1]] = np.array([1, 2]) # Works too.
为了使事情变得更奇怪,如果只是索引矩阵C
(而不是分配给它),似乎使用切片索引或列表只返回相同的内容:
C[0, 0:2] # => matrix([[ 1., 2.]])
C[0, [0, 1]] # => matrix([[ 1., 2.]])
问题是,为什么两种方法在分配中的行为不同?我错过了什么?
(编辑:错字)
答案 0 :(得分:2)
这似乎是numpy中的一个错误:http://projects.scipy.org/numpy/ticket/803。解决方案是分配普通列表或numpy数组,而不是为所选元素分配矩阵。
答案 1 :(得分:-1)
编辑:必须意识到,虽然我写的是真的,D[0,0:2] = ...
与D[0,[0,1]] = ...
不同的事实(因此对于数组)可能是真正的不一致(和相关的。)
就我所见,也许是为什么会发生这种情况。检查一下:
D[0,[0,1]] = np.array([[1,2]])
给出同样的错误。问题在于内部切片操作在矩阵形状再次“固定”到2D之前发生,因为matrix
是子类,当创建新视图时会发生,但这里否视图通常被创建为不必要的!
这意味着当您设置这样的元素时,它总是表现为:
C.A[0,[0,1]] = matrix([[1,2]]) # Note the C.A giving normal array view of C.
哪个失败了,因为矩阵是2D,但是C.A[0,[0,1]]
是1D(因为它不是“固定”到矩阵对象至少是2D),在这种情况下可以说,因为它只是删除右手边numpy的1维轴可能可以容忍它,但只要它没有它就会要求矩阵对象制作一个完整的自定义位置/赋值运算符,这些运算符也不是很好
但也许使用C.A
等可以帮助解决这个不便。但总的来说,在numpy中,最好总是使用基类数组,除非你进行了大量的矩阵乘法等(在这种情况下,如果它只限于程序的一部分,它可能更好地只是查看您的数组在它之前作为矩阵但在其余部分使用数组