How are slice indices of a numpy order array?

I have a np.array data (28,8,20) form, and I only need some records from it, so I take a snippet:

 In [41]: index = np.array([ 5, 6, 7, 8, 9, 10, 11, 17, 18, 19]) In [42]: extract = data[:,:,index] In [43]: extract.shape Out[43]: (28, 8, 10) 

So far so good, everything is as it should be. But now I wand to see only the first two entries in the last index for the first row:

 In [45]: extract[0,:,np.array([0,1])].shape Out[45]: (2, 8) 

Wait, this should be (8.2). He switched the indexes around, although it was not the last time I sliced! In my opinion, the following should act the same:

 In [46]: extract[0,:,:2].shape Out[46]: (8, 2) 

... but that gives me exactly what I wanted! As long as I have a 3D array, both methods seem to be equivalent:

 In [47]: extract[:,:,np.array([0,1])].shape Out[47]: (28, 8, 2) In [48]: extract[:,:,:2].shape Out[48]: (28, 8, 2) 

So what should I do if I want not only the first two entries, but also the wrong list? I could, of course, transpose the matrix after the operation, but it seems very controversial. The best solution to my problem is this (although it may be more elegant):

 In [64]: extract[0][:,[0,1]].shape Out[64]: (8, 2) 

Which brings us to the actual

Question:

I wonder what is the reason for this behavior? Anyone who decided that this was how he should work probably knew more about programming than I did, and thought it was so consistent with what I was missing. And I will most likely be banging my head about it if I don’t have a way to figure it out.

+8
python arrays numpy slice indexing
source share
2 answers

This is a case of (extended) partial indexing. There are 2 indexed arrays and 1 slice

If indexing subspaces are separated (by slice objects), then the space for indexing is transferred first, and then the sliced ​​subspace x.

http://docs.scipy.org/doc/numpy-1.8.1/reference/arrays.indexing.html#advanced-indexing

In the example of extended indexing, when the broadcast subspace ind_1 , ind_2 shape (2,3,4) :

However, x [:, ind_1,:, ind_2] has the form (2,3,4,10,30,50), since there is no single place for falling in the indexing subspace, therefore it is tied to the beginning. You can always use .transpose () to move a subspace anywhere.

In other words, this indexing does not match x[:, ind_1][[:,ind_2] . 2 arrays work together to define a subspace (2,3,4) .

In your example, extract[0,:,np.array([0,1])] means that the subspace (2,) ([0] and [0,1] acts together, not sequentially) and combines this with some average measurement.

A more complex example would be extract[[1,0],:,[[0,1],[1,0]]] , which creates an array (2,2,8) . This is the subspace (2,2) in the first and last dimensions plus the average. On the other hand, X[[1,0]][:,:,[[0,1],[1,0]]] creates a (2,8,2,2) , choosing one and the last measurement separately.

The key difference is whether indexed choices work sequentially or jointly. The syntax `[...] [...] is already available for sequential operation. Advanced indexing gives you a way to index together.

+5
source share

You're right, this is strange. I can only fear here. I think this is due to the fact that a[[0,1],[0,1],[0,1]].shape (2,) , not (2,2,2) and that a[0,1,[0,1,2]] really means a[[0,0,0],[1,1,1],[0,1,2]] , which evaluates to array([a[0,1,0],a[0,1,1],a[0,1,2]]) . That is, you go through index lists for each dimension in parallel, with length lists and scalars being transmitted in accordance with the longest.

Conceptually, this will make your extract[0,:,[0,1]] equivalent to extract[[0,0],[slice(None),slice(None)],[0,1]] (this syntax will not be accepted if you specify it manually). After passing the indexes, which will be evaluated before array([extract[0,slice(None),0],extract[0,slice(None),1]) . Each of the internal extracts is evaluated in the form of (8,) , therefore, the complete result is the form of (2,8) .

So, in conclusion, I believe that this is a side effect of broadcasting, which is done so that all sizes have an index list of the same length, which leads to the fact that : also broadcast. This is my hypothesis, but I did not look at the inner workings as numpy does. Perhaps the expert will come with a better explanation.

This hypothesis does not explain why extract[:,:,[0,1]] does not lead to the same behavior. I would have to postulate that the case of only the leading β€œ:” is special in order to avoid participating in the list index logic.

+3
source share

All Articles