检查两个数组是否可以在python中播放

时间:2017-11-11 22:28:54

标签: python numpy

根据文档(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

3 个答案:

答案 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以匹配

  • 再次比较;用另一个数组

  • 中的相应维度替换所有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