1

I have an array and want to change elements based on a classification using another array.

That is, I import one array, and then if the value of cell[i,j] is within a certain limit (say between 1 and 8) then multiply secondArray[i,j] by 0.3 and put result into an ouput array at place [i,j]

I have some code that does this (and probably explains what I mean a bit clearer) but it takes a 'very' long time (as my arrays are about 1000*1000 elements) and wondered if there is a more efficient solution.

Currently I have:

..
import numpy as np

def Factor_AM(cell):            
    if cell < 1     return 0.2;
    elif cell < 8:      return 0.3;
    else:       return 0.5;



mat = np.array(..some code to get an array from an external source..) //size 1000*1000
mat_out_1 = np.zeros_like(mat)
mat_out_1 = np.zeros_like(mat)

mat_ClassifyMe = np.array(..some code to import another 1000*1000 array with values in)

for index, x in np.ndenumerate(mat):
    mat_out_1[index] = Factor_AM(x) * mat_ClassifyMe[index]
    mat_out_2[index] = (1-Factor_AM(x)) * mat_ClassifyMe[index]

..some code to output mat_out_1 and mat_out_2

I saw some documentation on the np.where and np.argwhere functions that look hopeful, but given I have more than 1 test (in the above code I have 3 but in reality I have 12) I can't think of a way without making very ugly nested statements.

Is there another way to do this, or is this as efficient as Python gets?

2 Answers 2

1

You can use Boolean or “mask” index arrays for this purpose, for example:

import numpy as np

mat = np.arange(16.0).reshape((4,4))

mat_out = np.zeros_like(mat)

mat_out[mat < 6] = 0.2 * mat[mat < 6]  # using a conditional for indexing
# or use a variable for the boolean 'masking' index array
mask1 = np.logical_and(mat >= 6, mat < 10)
mat_out[mask1] = 0.3 * mat[mask1]
mask2 = mat >= 10
mat_out[mask2] = 0.5 * mat[mask2]

print mat
print mat < 6
print mask1
print mat_out
Sign up to request clarification or add additional context in comments.

2 Comments

thanks, that looks like what I need. I'll run the code through with some timers to see what the difference is in a bit.
Time results: inner loop (i.e. minus overheads for accessing and outputing arrays to other programmes, just looking at the filtering of the matrices) ~25s to ~0.5s Given I'm doing this a few hundred times, thats a very meaningful speed increase. Cheers.
0
mat = np.array([0.1, 0.2, 5, 4, 9, 0.05, 2, 11]) # an example of input #1
mat_ClassifyMe = np.ones_like(mat) # an example of input #2
mask1 = mat < 1
mask2 = mat >= 8
f = np.empty_like(mat)
f[mask1] = 0.2
f[mask2] = 0.5
f[np.logical_not(mask1 | mask2)] = 0.3
mat_out_1 = f * mat_ClassifyMe
mat_out_2 = (1 - f) * mat_ClassifyMe

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.