im using numpy 2d arrays. I want to copy values from one array to another array, but only if an expression is true.

e.g.

for row in range(len(anImage1)):
  for col in range(len(anImage1[0])):
    if col > 100:
      anImage1[row][col] = min(anImage1[row][col], anImage2[row][col])

or

for row in range(len(anImage1)):
  for col in range(len(anImage1[0])):
    if anImageMask[row][col] == 255:
      anImage1[row][col] = anImage2[row][col]

I know this is a very poor and slow solution... Can somebody explain me how to speed up the code?

share
up vote 2 down vote accepted

Assume that the anImage1 and anImage12 are 256 by 256.

anImage1 = np.random.randint(0, 255, (256, 256))
anImage2 = np.random.randint(0, 255, (256, 256))

Just, the first condition can be replaced by (updated min to minimum. see @jaime's comment)

anImage1[:, 101:] = np.minimum(anImage1[:, 101:], anImage2[:, 101:], axis=0)

and the second condition is:

cond = anImage1 == 255
anImage1[cond] = anImage2[cond]

Avoid loop is important to optimize numpy performance.

share
    
Thank you very much!!! It always looks so easy :-D – retro009 Jul 22 '14 at 8:01
    
Your use of np.min is inefficient, as it has to create an intermediate array stacking both images. You can get the same result efficiently with np.minimum. – Jaime Jul 22 '14 at 11:44
    
@Jaime I didn't know about that. Thanks for let us know! – emeth Jul 22 '14 at 11:46

Depends. If you have no information about where in the array your condition is true, you have no choice but to check the condition for each element in the array. In that case writing code like

for i in xrange(len(A)):
  for j in xrange(len(A[0])):
    if condition(A[i][j])
      B[i][j] = A[i][j]

is unavoidable. If you find yourself doing this repeatedly with the same condition, you might use a trick like storing the indices for which the condition is true, e.g.

source = ["a", "b", "c", "a"]
dest = [None]*len(source)
condition = lambda x : x == "a"
indices = [i for i in xrange(len(source)) if condition(source[i])]
for index in indices:
    dest[index] = source[index]

Hope this helps.

share

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.