我有一个与Python数组形状相关的问题。
数组大小(2, )
和(2, 1)
之间有什么区别?
我试图将这两个数组相加。然而,我得到了以下错误:
形状为(2, )的不可广播输出操作数与广播形状(2, 2)不匹配
arr1 += arr2
to:
arr1 = arr1 + arr2
它将愉快地创建一个新的(2, 2)
数组。或者,如果目标是让2x1的数组像一个平坦的1D数组一样工作,你可以使用flatten
函数:
alreadyflatarray += twodarray.flatten()
(2,) 是一维数组,(2,1) 是只有一列的矩阵
您可以通过使用 np.zero
并传递所需的形状来轻松地创建全零数组,从而清楚地看到它们之间的区别:
>>> np.zeros((2,))
array([0., 0.])
>>> np.zeros((2,1))
array([[0.],
[0.]])
@yx131,你可以看下面的代码,以便清晰地了解元组及其在定义numpy数组形状中的使用。
注意: 不要忘记查看下面的代码,它有关于numpy广播相关问题的解释。
另外请查看numpy的广播规则:https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html。
在编程中,(2)
和(2,)
之间有一个区别。第一个是字面值2
,而第二个是一个元组。
(2,)
是一个包含1个项目的元组,(2, 2)
是一个包含2个项目的元组。在代码示例中很清楚。
注意:对于numpy数组来说,(2,)
表示包含2个项目的一维数组的形状,(2, 2)
表示包含2行2列的二维数组(矩阵)的形状。如果要将两个数组相加,则它们的形状应该相同。v = (2) # Assignment of value 2
t = (2,) # Comma is necessary at the end of item to define 1 item tuple, it is not required in case of list
t2 = (2, 1) # 2 item tuple
t3 = (3, 4) # 2 item tuple
print(v, type(v))
print(t, type(t))
print(t2, type(t2))
print(t3, type(t3))
print(t + t2)
print(t2 + t3)
"""
2 <class 'int'>
(2,) <class 'tuple'>
(2, 1) <class 'tuple'>
(3, 4) <class 'tuple'>
(2, 2, 1)
(2, 1, 3, 4)
"""
# Python 3.5.2
import numpy as np
arr1 = np.array([1, 4]);
arr2 = np.array([7, 6, 3, 8]);
arr3 = np.array([3, 6, 2, 1]);
print(arr1, ':', arr1.shape)
print(arr2, ":", arr2.shape)
print(arr3, ":", arr3.shape)
print ("\n")
"""
[1 4] : (2,)
[7 6 3 8] : (4,)
[3 6 2 1] : (4,)
"""
# Changing shapes (dimensions)
arr1.shape = (2, 1)
arr2.shape = (2, 2)
arr3.shape = (2, 2)
print(arr1, ':', arr1.shape)
print(arr2, ":", arr2.shape)
print(arr3, ":", arr3.shape)
print("\n")
print(arr1 + arr2)
"""
[[1]
[4]] : (2, 1)
[[7 6]
[3 8]] : (2, 2)
[[3 6]
[2 1]] : (2, 2)
[[ 8 7]
[ 7 12]]
"""
arr1.shape = (2, )
print(arr1, arr1.shape)
print(arr1 + arr2)
"""
[1 4] (2,)
[[ 8 10]
[ 4 12]]
"""
# Code with error(Broadcasting related)
arr2.shape = (4,)
print(arr1+arr2)
"""
Traceback (most recent call last):
File "source_file.py", line 53, in <module>
print(arr1+arr2)
ValueError: operands could not be broadcast together
with shapes (2,) (4,)
"""
所以在你的情况下,问题与需要添加的不匹配的维度有关(根据numpy的广播)。谢谢。
In [164]: a = np.array([3,6])
In [165]: a
Out[165]: array([3, 6])
In [166]: a.shape
Out[166]: (2,)
In [167]: a.reshape(2,1)
Out[167]:
array([[3],
[6]])
In [168]: a.reshape(1,2)
Out[168]: array([[3, 6]])
第一个显示为简单列表 [3,6]
。第二个则是具有 2 个嵌套列表的列表。第三个则是具有一个嵌套列表和 2 个项目的列表。因此,形状和列表嵌套之间存在着一致的关系。
In [169]: a + a
Out[169]: array([ 6, 12]) # shape (2,)
In [170]: a + a.reshape(1,2)
Out[170]: array([[ 6, 12]]) # shape (1,2)
In [171]: a + a.reshape(2,1)
Out[171]:
array([[ 6, 9], # shape (2,2)
[ 9, 12]])
维度的行为如下:
(2,) + (2,) => (2,) (2,) + (1,2) => (1,2) + (1,2) => (1,2) (2,) + (2,1) => (1,2) + (2,1) => (2,2) + (2,2) => (2,2)
这意味着较低维度的数组可以通过添加前导大小为1的维度来扩展到匹配的维度数量。
并且大小为1的维度可以更改以匹配相应的维度。
我怀疑您在执行 a += ...
时遇到了错误(如果是这样,您应该清楚地说明)。
In [172]: a += a
In [173]: a += a.reshape(1,2)
....
ValueError: non-broadcastable output operand with shape (2,)
doesn't match the broadcast shape (1,2)
In [175]: a += a.reshape(2,1)
...
ValueError: non-broadcastable output operand with shape (2,)
doesn't match the broadcast shape (2,2)
使用 a+=...
进行加法运算时,结果的形状被固定为 (2,),这是由 a
的形状所决定的。但正如上面所述,这两个加法操作会生成形状为 (1,2) 和 (2,2) 的结果,它们与 (2,) 不兼容。
同样的推理可以解释这些加法操作和错误:
In [176]: a1 = a.reshape(1,2)
In [177]: a1 += a
In [178]: a1
Out[178]: array([[12, 24]])
In [179]: a2 = a.reshape(2,1)
In [180]: a2 += a
...
ValueError: non-broadcastable output operand with shape (2,1)
doesn't match the broadcast shape (2,2)
In [182]: a1 += a2
...
ValueError: non-broadcastable output operand with shape (1,2)
doesn't match the broadcast shape (2,2)
numpy
数组的形状属性。 - juanpa.arrivillaga