4

I have an numpy array

import numpy as np

a = np.array([
[999, 999, 999, 999, 999, 999, 999, 999, 999, 999],
[999, 999, 999, 1, 2, 3, 4, 999, 999, 999],
[999, 999, 999, 5, 6, 7, 8, 999, 999, 999],
[999, 999, 999, 9, 10, 11, 12, 999, 999, 999],
[999, 999, 999, 999, 999, 999, 999, 999, 999, 999]])

how to return the filtered values, containing only the different values than 999 using numpy slicing?

filtered = np.where(a != 999)
In [5]: filtered
Out[5]: 
(array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4,
    4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
    6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9,
    9, 9, 9, 9, 9, 9, 9, 9]),
 array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
    3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
    6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8,
    9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
    2, 3, 4, 5, 6, 7, 8, 9]))

Desired output:

output = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]])
0

3 Answers 3

1

You can do the following:

>>> mask = (a!=999)
>>> dim1 = np.any(mask, axis=1).sum()
>>> a[mask].reshape(dim1, -1)
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])

This of course assume that you only have a single contiguous box in the whole array.

Sign up to request clarification or add additional context in comments.

1 Comment

A good solution for the special case. May raise ValueError for "other" cases
1

Yours is a special case, because the subarray is rectangular. You can get the flat values using fancy indexing:

>>> a[filtered]
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])

And if you know the shape already, you can reshape that:

>>> a[filtered].reshape(3,4)
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])

However, there can be no guarantee that the input data will leave you with a rectangular array after the filtering in the general case. Consider, for example, what output array should look like if the input array had a[0,0] == 13.

7 Comments

Sorry. I did not read your modifications, before my comments. The main problem is that I really don't know the shape of the valid numbers inside the matrix. This is only an raw example. In my case I'll not get an outside number as pointed out by @wim (i.e. a[0,0] == 13)
Your question is not well defined by the example you have given.
Give the desired output where the valid numbers are not neatly contained inside a rectangle, for example if a[0,1] != 999 with all other things being the same.
And what if an element inside the box is equal to 999 ?
Do you prefer that I edit my question and insert a statement which that I don't know the index of those valid values? In the case you have suggested the .reshape(3,4) visually based?
|
1

You can also do this. Create a 2D mask using the condition. Typecast the condition mask to int or float, depending on the array, and multiply it with the original array.

In [8]: arr
Out[8]: 
array([[ 1.,  2.,  3.,  4.,  5.],
       [ 6.,  7.,  8.,  9., 10.]])

In [9]: arr*(arr % 2 == 0).astype(np.int) 
Out[9]: 
array([[ 0.,  2.,  0.,  4.,  0.],
       [ 6.,  0.,  8.,  0., 10.]])

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.