1

I have a question about masking/slicing the 2D numpy array using a boolean mask. Here I have a np 2D-array x, which is

x=np.tile(np.arange(10).reshape(10,1),(1,10))
[[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]]

The x is a 10 by 10 array, whose each column is the same. If there is any better way to generate this, could you please point that out? Thanks. Then there is a boolean array,

y=(x!=np.arange(10))
[[False  True  True  True  True  True  True  True  True  True]
[ True False  True  True  True  True  True  True  True  True]
[ True  True False  True  True  True  True  True  True  True]
[ True  True  True False  True  True  True  True  True  True]
[ True  True  True  True False  True  True  True  True  True]
[ True  True  True  True  True False  True  True  True  True]
[ True  True  True  True  True  True False  True  True  True]
[ True  True  True  True  True  True  True False  True  True]
[ True  True  True  True  True  True  True  True False  True]
[ True  True  True  True  True  True  True  True  True False]]

Now, I want to get the resulting array like,

[[1 0 0 0 0 0 0 0 0 0]
[2 2 1 1 1 1 1 1 1 1]
[3 3 3 2 2 2 2 2 2 2]
[4 4 4 4 3 3 3 3 3 3]
[5 5 5 5 5 4 4 4 4 4]
[6 6 6 6 6 6 5 5 5 5]
[7 7 7 7 7 7 7 6 6 6]
[8 8 8 8 8 8 8 8 7 7]
[9 9 9 9 9 9 9 9 9 8]]

The elements in x whose corresponding position in y has value False are removed, and the new 2D-array is returned. So how could I get this for this situation?

Thanks very much for your help.

Mr_Pi
  • 31
  • 8

1 Answers1

2

x[y] selects values from x where y is True. The array x[y] is 1-dimensional however. You could reshape it to have 9 rows (and however many columns which makes sense) using reshape(9,-1). To get the desired result, you would then have to flip the array left-to-right:

In [81]: np.fliplr(x[y].reshape(9,-1))
Out[84]: 
array([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [2, 2, 1, 1, 1, 1, 1, 1, 1, 1],
       [3, 3, 3, 2, 2, 2, 2, 2, 2, 2],
       [4, 4, 4, 4, 3, 3, 3, 3, 3, 3],
       [5, 5, 5, 5, 5, 4, 4, 4, 4, 4],
       [6, 6, 6, 6, 6, 6, 5, 5, 5, 5],
       [7, 7, 7, 7, 7, 7, 7, 6, 6, 6],
       [8, 8, 8, 8, 8, 8, 8, 8, 7, 7],
       [9, 9, 9, 9, 9, 9, 9, 9, 9, 8]])
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • Thanks for your reply. I also used x[y] and found it formed a 1D array. But why it should be flipped to get desired result? Btw, what is the -1 here in reshape. i normally use like reshape(9,10) to reshape. – Mr_Pi Nov 08 '16 at 03:28
  • [When using reshape](https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html) one dimension can be `-1`. It tells reshape to infer the actual dimension length based on the size of the array and the other dimension lengths. It basically means, "do the right thing." Now `reshape` [does not change the order](http://stackoverflow.com/a/35226493/190597) of the elements. `x[y]` begins with `0, 0, 0, 0, 0, 0, 0, 0, 0, 1`. If you want `1, 0, 0, 0, 0, 0, 0, 0, 0, 0` then the array has to be flipped. – unutbu Nov 08 '16 at 10:04
  • Thanks for reply. The method you provide can work under this situation. I have a question, what if there are more than one False in each column of array y (the boolean array), then I found your method cannot work every times. Do you have any suggestions for this situation? Thanks. – Mr_Pi Nov 08 '16 at 17:50
  • It's not clear to me what, in that case, the desired result should be. Can you give an example? – unutbu Nov 08 '16 at 20:00