使用索引数组广播 numpy 矩阵
Broadcasting numpy matrices using arrays of indices
我有这些 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
可能具有比列向量更一般的形状。
不要使用 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))
(2,)
(2,)
array([[1],
[4],
[5]])
如果要进行矩阵乘法,请使用 @
运算符,如果您使用的 Python 版本太旧或 NumPy 版本太旧,则使用 dot
方法有 @
.
使用 simpe 建立索引 [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
今天早些时候有一个类似的问题:
使用 *
进行矩阵乘法的便利很少超过将维度限制为 2 的笨拙。np.dot
也同样有效。数组还提供 tensordot
、einsum
和 matmul
(以及 @
运算符)。
np.matrix
是 np.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
我有这些 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
可能具有比列向量更一般的形状。
不要使用 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))
(2,)
(2,)
array([[1],
[4],
[5]])
如果要进行矩阵乘法,请使用 @
运算符,如果您使用的 Python 版本太旧或 NumPy 版本太旧,则使用 dot
方法有 @
.
使用 simpe 建立索引 [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
今天早些时候有一个类似的问题:
使用 *
进行矩阵乘法的便利很少超过将维度限制为 2 的笨拙。np.dot
也同样有效。数组还提供 tensordot
、einsum
和 matmul
(以及 @
运算符)。
np.matrix
是 np.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