3

I have a function which can take an np.ndarray of shape (3,) or (3, N), or (3, N, M), etc.. I want to add to the input array an array of shape (3,). At the moment, I have to manually check the shape of the incoming array and if neccessary, expand the array that is added to it, so that I don't get a broadcasting error. Is there a function in numpy that can expand my array to allow broadcasting for an input array of arbitrary depth?

def myfunction(input_array):
    array_to_add = np.array([1, 2, 3])
    if len(input_array.shape) == 1:
        return input_array + array_to_add
    elif len(input_array.shape) == 2:
        return input_array + array_to_add[:, None]
    elif len(input_array.shape) == 3:
        return input_array + array_to_add[:, None, None]
    ...

2 Answers 2

1

One option would be to transpose before and after the addition:

(input_array.T + array_to_add).T

You could also use expand_dims to add the extra dimensions:

(np.expand_dims(array_to_add, tuple(range(1, input_array.ndim)))
 + input_array
)

Alternatively with broadcast_to on the reversed shape of input_array + transpose:

(np.broadcast_to(array_to_add, input_array.shape[::-1]).T
 + input_array
)

Or with a custom reshape:

(array_to_add.reshape(array_to_add.shape+(1,)*(input_array.ndim-1))
 + input_array
)
Sign up to request clarification or add additional context in comments.

2 Comments

Awesome! Thanks for the multitude of solutions. Why does the transpose-version work? Does broadcasting begin at the last dimension?
Yes, broadcasting is aligned on the trailing dimensions, which would become the leading ones in the transpose.
0

To broadcast, Use the below formulae :

new_shape = (1,) *  (input_array.ndim -1) + array_to_add.shape

Code :

import numpy as np

array1 = np.array([[1, 2], [3, 4], [5, 6]])
array2 = np.array([10, 20])

print(array1.shape)#(3, 2)
print(array2.shape)#(2,)

print(array1.shape[-1])#2
print(array2.shape[0])#2


array_to_add = array2 
input_array = array1 

if  input_array.shape[-1] != array_to_add.shape[0] : 
    raise ValueError('Shapes are incompatable.')

new_shape = (1,) *  (input_array.ndim -1) + array_to_add.shape   

'''
new_shape :
(1, 2)
'''
array_to_add_expanded = array_to_add.reshape(new_shape)
'''
array_to_add_expanded :
[[10 20]]
'''
res = input_array + array_to_add_expanded
print(res)
'''
[[11 22]
 [13 24]
 [15 26]]
'''

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.