使用索引数组广播numpy矩阵

时间:2017-05-18 20:23:04

标签: python numpy numpy-broadcasting

我有这些numpy对象:

>>> x = np.matrix([[1],[2],[3]])
>>> i = ([1,2],0)
>>> y = np.matrix([[4],[5]])

当我做x[i]时,我得到了我期望的结果:

>>> x[i]
matrix([[2],
        [3]])

但是,当我尝试分配给x[i]时,我会得到时髦的行为:

>>> x[i] = y
ValueError: array is not broadcastable to correct shape
>>> y.shape
(2, 1)
>>> x[i].shape
(2, 1)

我已经找到了一些解决方法,但它们是解决方法,而不是我想要的:

>>> x[1:,0] = y
>>> x
matrix([[1],
        [4],
        [5]])
>>> x = np.array([[1],[2],[3]]); y = np.array(y)
>>> x[i] = y[:,0]
>>> x
array([[1],
       [4],
       [5]])

第二种解决方法是不可接受的,因为y可能具有比列向量更一般的形状。

2 个答案:

答案 0 :(得分:1)

不要使用numpy.matrix。太可怕了。它导致了许多奇怪的不兼容性,并且有很多不一致,包括这个。

使用numpy.array。对于数组,x[i]是一维的,并且为y分配相同形状的一维x[i]将会正常工作。

import numpy

x = numpy.array([[1], [2], [3]])
y = numpy.array([4, 5])
i = ([1, 2], 0)

print(x[i].shape)
print(y.shape)

x[i] = y

print(repr(x))

Output

(2,)
(2,)
array([[1],
       [4],
       [5]])

如果您想进行矩阵乘法运算,请使用@运算符或dot方法,如果您的Python版本太旧或NumPy版本太旧而无法@ 1}}。

答案 1 :(得分:0)

使用简化[1,2]进行索引:

In [71]: x
Out[71]: 
matrix([[1],
        [2],
        [3]])
In [72]: y
Out[72]: 
matrix([[4],
        [5]])
In [73]: x[[1,2],:]
Out[73]: 
matrix([[2],
        [3]])
In [74]: x[[1,2],:] = y

尝试使用元组有问题:

In [78]: i = ([1,2],0)
In [79]: x[i] = y
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-79-699d63749224> in <module>()
----> 1 x[i] = y

ValueError: shape mismatch: value array of shape (2,1) could not be broadcast to indexing result of shape (2,)

i更改为i = ([1,2],slice(None))符合我的第一个案例。

使用0代替:'也是一个问题:

In [82]: x[[1,2],0] = y
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-82-8b683eb93954> in <module>()
----> 1 x[[1,2],0] = y

ValueError: shape mismatch: value array of shape (2,1) could not be broadcast to indexing result of shape (2,)

我怀疑在将结果转换回矩阵之前,它正尝试将(2,)作为numpy数组进行识别。

尝试相当于:

In [83]: x.A[[1,2],0] = y
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-83-b2ccc78af912> in <module>()
----> 1 x.A[[1,2],0] = y

ValueError: shape mismatch: value array of shape (2,1) could not be broadcast to indexing result of shape (2,)

因为它需要展平版y

In [84]: x.A[[1,2],0] = y.A1    # max `y` a 1d array
x[[1,2],0] = y.A1       # also works

今天早些时候出现了类似的问题:Copy NumPy matrix into NumPy array

使用*进行矩阵乘法的便利性很少超过将维度限制为2的笨拙。np.dot同样适用。数组还提供tensordoteinsummatmul(以及@运算符)。

np.matrixnp.ndarray的子类。它继承了方法。通常它使用ndarray方法执行操作,并清除维数,将1d结果强制为2d或标量。

这里是*矩阵乘法的代码:

Signature: x.__mul__(other)
Source:   
    def __mul__(self, other):
        if isinstance(other, (N.ndarray, list, tuple)) :
            # This promotes 1-D vectors to row vectors
            return N.dot(self, asmatrix(other))
        if isscalar(other) or not hasattr(other, '__rmul__') :
            return N.dot(self, other)
        return NotImplemented