Multiply numpy ndarray by 1d array along this axis

I seem to be lost in something potentially stupid. I have a numpy n-dimensional array and I want to propagate it using a vector array (1d) along some dimension (which could change!). For example, I want to multiply a 2d array by a 1d array along the 0 axis of the first array, I can do something like this:

a=np.arange(20).reshape((5,4)) b=np.ones(5) c=a*b[:,np.newaxis] 

Simple, but I would like to expand this idea to n-measures (for a, and b is always 1d) and any axis. In other words, I would like to know how to create a slice with np.newaxis in the right place. Let's say that a is 3d, and I want to multiply along the axis = 1, I would like to create a slice that would give correctly:

 c=a*b[np.newaxis,:,np.newaxis] 

those. given the number of measurements a (say 3) and the axis I want to multiply (for example, axis = 1), how do I generate and pass the slice:

 np.newaxis,:,np.newaxis 

Thanks.

+6
source share
2 answers

Solution Code -

 import numpy as np # Given axis along which elementwise multiplication with broadcasting # is to be performed given_axis = 1 # Create an array which would be used to reshape 1D array, b to have # singleton dimensions except for the given axis where we would put -1 # signifying to use the entire length of elements along that axis dim_array = np.ones((1,a.ndim),int).ravel() dim_array[given_axis] = -1 # Reshape b with dim_array and perform elementwise multiplication with # broadcasting along the singleton dimensions for the final output b_reshaped = b.reshape(dim_array) mult_out = a*b_reshaped 

Run example to demonstrate steps -

 In [149]: import numpy as np In [150]: a = np.random.randint(0,9,(4,2,3)) In [151]: b = np.random.randint(0,9,(2,1)).ravel() In [152]: whos Variable Type Data/Info ------------------------------- a ndarray 4x2x3: 24 elems, type `int32`, 96 bytes b ndarray 2: 2 elems, type `int32`, 8 bytes In [153]: given_axis = 1 

Now we want to perform stepwise multiplication along the given axis = 1 . Let create a dim_array :

 In [154]: dim_array = np.ones((1,a.ndim),int).ravel() ...: dim_array[given_axis] = -1 ...: In [155]: dim_array Out[155]: array([ 1, -1, 1]) 

Finally, change form b and do elemental multiplication:

 In [156]: b_reshaped = b.reshape(dim_array) ...: mult_out = a*b_reshaped ...: 

Check the whos information again and pay particular attention to b_reshaped and mult_out :

 In [157]: whos Variable Type Data/Info --------------------------------- a ndarray 4x2x3: 24 elems, type `int32`, 96 bytes b ndarray 2: 2 elems, type `int32`, 8 bytes b_reshaped ndarray 1x2x1: 2 elems, type `int32`, 8 bytes dim_array ndarray 3: 3 elems, type `int32`, 12 bytes given_axis int 1 mult_out ndarray 4x2x3: 24 elems, type `int32`, 96 bytes 
+7
source

You can create a slice object and select the desired dimension:

 import numpy as np a = np.arange(18).reshape((3,2,3)) b = np.array([1,3]) ss = [None for i in range(a.ndim)] ss[1] = slice(None) # set the dimension along which to broadcast print ss # [None, slice(None, None, None), None] c = a*b[ss] 
+2
source

Source: https://habr.com/ru/post/986507/


All Articles