2

This is probably a really simple question, but I am not figuring this out.

I have a 2D numpy array, which is of shape (3,2) and a 1D array of shape (3,):

    A = [[2,4],[6,8][10,12]]
    B = [1,2,4]

I would like to divide array A by array B, resulting in:

   [[2,4],[3,4][2.5,3]]

But numpy will not let me do this, I think because the shape is not right. I get the familiar 'operands could not be broadcast together with shapes (10,2) (10,)' error.

I tried things with reshape and swapaxis, but it is not working. I would much prefer to be able to do this without a for loop (because I need to do this many many times with large arrays) and without having to swap the axis of array A (because other arrays are if this shape).

Can you guys help me?

Divakar
  • 218,885
  • 19
  • 262
  • 358
user90465
  • 187
  • 2
  • 13
  • Did you try `np.reshape([1,2,4], (3,1))`? A (10,) array can broadcast to (1,10) and on to (2,10). But adding a dimension at the other end requires explicit action on your part. – hpaulj Feb 01 '17 at 20:40
  • [General Broadcasting Rules](https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html#general-broadcasting-rules) – wwii Feb 01 '17 at 20:49

1 Answers1

4

Extend B to 2D and then divide -

A/B[:,None].astype(float)

Sample run -

In [9]: A
Out[9]: 
array([[ 2,  4],
       [ 6,  8],
       [10, 12]])

In [10]: B
Out[10]: array([1, 2, 4])

In [11]: A/B[:,None].astype(float)
Out[11]: 
array([[ 2. ,  4. ],
       [ 3. ,  4. ],
       [ 2.5,  3. ]])

Or use from __future__ import division that takes care of division to result in a floating pt array -

In [14]: from __future__ import division

In [15]: A/B[:,None]
Out[15]: 
array([[ 2. ,  4. ],
       [ 3. ,  4. ],
       [ 2.5,  3. ]])

Performance boost with multiplication by reciprocal -

In [32]: A = np.random.rand(300,200)

In [33]: B = np.random.rand(300)

In [34]: from __future__ import division

In [35]: %timeit A/B[:,None]
1000 loops, best of 3: 336 µs per loop

In [36]: %timeit A*(1.0/B[:,None])
10000 loops, best of 3: 101 µs per loop

More info on this could be found here. Also, one needs to be careful using this method though, if the values of B are extremely close to 0.

Community
  • 1
  • 1
Divakar
  • 218,885
  • 19
  • 262
  • 358