Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

If I have an array, A, with shape (n, m, o) and an array, B, with shape (n, m), is there a way to divide each array at A[n, m] by the scalar at B[n, m] without a list comprehension?

>>> A.shape
(4,173,1469)
>>> B.shape
(4,173)
>>> # Better way to do:
>>> np.array([[A[i, j] / B[i, j] for j in range(len(B[i]))] for i in range(len(B))])

The problem with a list comprehension is that it is slow, it doesn't return an array (so you have to np.array(_) it, which makes it even slower), it is hard to read, and the whole point of numpy was to move loops from Python to C++ or Fortran.

If A was of shape (n) and B was a scalar (of shape ( )), then this would be trivial: A / B, but this property does not scale with dimensions

>>> A / B
ValueError: operands could not be broadcast together with shapes (4,173,1469) (4,173) 

I am looking for a fast way to do this (preferably not by tiling B to an array of shape (n, m, o), and preferably using native numpy tools).

share|improve this question

2 Answers 2

up vote 1 down vote accepted

You are absolutely right, there is a better way, I think you are getting the spirit of numpy. The solution in your case is that you have to add a new dimension to B that consists of one entry in that dimension: so if your A is of shape (n,m,o) your B has to be of shape (n,m,1) and then you can use the native broadcasting to get your operation "A/B" done. You can just add that dimension to be by adding a "newaxis" to B there.

import numpy as np
A = np.ones(10,5,3)
B = np.ones(10,5)
Result = A/B[:,:,np.newaxis]

B[:,:,np.newaxis] --> this will turn B into an array of shape of (10,5,1)

share|improve this answer
    
You might want to try B[..., None] for a more elegant solution. –  Ophion Feb 2 '14 at 22:34

From here, the rules of broadcasting are:

When operating on two arrays, NumPy compares their shapes element-wise. It starts with the trailing dimensions, and works its way forward. Two dimensions are compatible when

they are equal, or
one of them is 1

Your dimensions are n,m,o and n,m so not compatible.

The / division operator will work using broadcasting if you use:

  1. o,n,m divided by n,m
  2. n,m,o divided by n,m,1
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.