根据文档(https://docs.scipy.org/doc/numpy/reference/ufuncs.html),如果满足下列条件之一,则可以播放两个数组:
- The arrays all have exactly the same shape.
- The arrays all have the same number of dimensions and the length of each dimensions is either a common length or 1.
- Arrays that have too few dimensions can have their shapes prepended with a dimension of length 1 to satisfy property 2.
我试图在python中实现这一点,但在理解第二和第三条规则时遇到了麻烦。没有得到我期待的答案,但我想知道我在代码中犯了什么错误以及这个错误的可能解决方案。
# Broadcastable if:
# The arrays all have exactly the same shape.
if a.shape == b.shape:
result = True
# The arrays all have the same number of dimensions
elif len(a.shape) == len(b.shape):
# and the length of each dimensions is either a common length or 1.
for i in len(a.shape):
if len(a.shape[i] != 1):
result = False
else:
result = True
# Arrays that have too few dimensions can have their shapes prepended with a dimension of length 1 to satisfy property 2
elif a.shape == () or b.shape == ():
result = True
else:
result = False
return result
答案 0 :(得分:4)
这是一个简洁的表达式,用于检查两个数组是否可播放:
In [101]: import numpy as np
In [102]: a = np.zeros((3, 1, 5))
In [103]: b = np.zeros((4, 5))
In [104]: all((m == n) or (m == 1) or (n == 1) for m, n in zip(a.shape[::-1], b.shape[::-1]))
Out[104]: True
In [105]: b = np.zeros((5, 3))
In [106]: all((m == n) or (m == 1) or (n == 1) for m, n in zip(a.shape[::-1], b.shape[::-1]))
Out[106]: False
答案 1 :(得分:1)
我还没有尝试将其作为代码实现,但我推理的方式是:
比较形状
如果尺寸较小,请在开头添加1以匹配
再次比较;用另一个数组
例如,如果我有一个(3,1)和(3,)数组。将(3,)扩展为(1,3)。现在改为(3,3)。
In [180]: A = np.ones((3,1),int); B = np.arange(3)
In [181]: A.shape
Out[181]: (3, 1)
In [182]: B.shape
Out[182]: (3,)
In [183]: (A+B)
Out[183]:
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
In [184]: np.broadcast_arrays(A,B)
Out[184]:
[array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]]),
array([[0, 1, 2],
[0, 1, 2],
[0, 1, 2]])]
在最近的另一个问题中,我使用broadcast_to
。我从一个n-d数组开始,使用np.mean
(和keepdims)将一维减少到1,然后使用broadcast_to
重新展开它。
Arbitrary N-dimensional repeat of N-dimensional numpy array
在最近的回答中,https://stackoverflow.com/a/47243071/901925
a(2,3)用(4,3)
播出 A[:, None]
将(4,3)变为(4,1,3)(这是一个隐含的决赛':#39;)。 B
自动从(2,3)扩展到(1,2,3)。现在两者都可以广播到(4,2,3)。
因此(2,3)不能用(4,3)(相同的n-d但不同的值)广播。但它可以用(4,1,3)广播。
答案 2 :(得分:0)
使用numpy
自己的broadcast
函数的情况与此相同:
def can_be_broadcast(*args):
try:
numpy.broadcast(*args)
return True
except ValueError:
return False