What is the best way to test whether an array can be broadcast to a given shape?
The "pythonic" approach of try
ing doesn't work for my case, because the intent is to have lazy evaluation of the operation.
I'm asking how to implement is_broadcastable
below:
>>> x = np.ones([2,2,2])
>>> y = np.ones([2,2])
>>> is_broadcastable(x,y)
True
>>> y = np.ones([2,3])
>>> is_broadcastable(x,y)
False
or better yet:
>>> is_broadcastable(x.shape, y.shape)
A set of arrays is called “broadcastable” to the same shape if the above rules produce a valid result. For example, if a.shape is (5,1), b.shape is (1,6), c.shape is (6,) and d.shape is () so that d is a scalar, then a, b, c, and d are all broadcastable to dimension (5,6); and.
The rank of the array is the number of dimensions. The shape of the array is a tuple of integers giving the size of the array along each dimension.
Broadcasting with Two Three-dimensional Arrays And, for the other dimension, one of the dimensions is one. So an arithmetic operation is possible. But if you try to add two arrays which cannot be broadcasted due to incompatible shapes, you will get an error.
I really think you guys are over thinking this, why not just keep it simple?
def is_broadcastable(shp1, shp2):
for a, b in zip(shp1[::-1], shp2[::-1]):
if a == 1 or b == 1 or a == b:
pass
else:
return False
return True
If you just want to avoid materializing an array with a given shape, you can use as_strided:
import numpy as np
from numpy.lib.stride_tricks import as_strided
def is_broadcastable(shp1, shp2):
x = np.array([1])
a = as_strided(x, shape=shp1, strides=[0] * len(shp1))
b = as_strided(x, shape=shp2, strides=[0] * len(shp2))
try:
c = np.broadcast_arrays(a, b)
return True
except ValueError:
return False
is_broadcastable((1000, 1000, 1000), (1000, 1, 1000)) # True
is_broadcastable((1000, 1000, 1000), (3,)) # False
This is memory efficient, since a and b are both backed by a single record
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With