Combining slicing and broadcast indexing for numpy multidimensional arrays

I have an ND numpy array (say, for example, 3x3x3) from which I would like to extract a submatrix by combining slices and index arrays. For example:

import numpy as np  
A = np.arange(3*3*3).reshape((3,3,3))
i0, i1, i2 = ([0,1], [0,1,2], [0,2])
ind1 = j0, j1, j2 = np.ix_(i0, i1, i2)
ind2 = (j0, slice(None), j2)
B1 = A[ind1]
B2 = A[ind2]

I would expect B1 == B2, but in fact, different forms

>>> B1.shape
(2, 3, 2)
>>> B2.shape
(2, 1, 2, 3)
>>> B1
array([[[ 0,  2],
        [ 3,  5],
        [ 6,  8]],

       [[ 9, 11],
        [12, 14],
        [15, 17]]])
>>> B2
array([[[[ 0,  3,  6],
         [ 2,  5,  8]]],

       [[[ 9, 12, 15],
         [11, 14, 17]]]])

Does anyone understand why? Any idea on how I can get "B1" by manipulating only objects "A" and "ind2"? The goal is that it will work for any nD arrays and that I don’t have to look for the shape of the sizes that I want to completely preserve (I hope I'm clear enough :)). Thanks!!
--- EDIT ---
To be clearer, I would like to have a fun function, so

A[fun(ind2)] == B1
+1
3

ind1 (2,), (3,), (2,), B - (2,3,2). .

ind2 - () . 2 1 . :

( ), , x.

(2,2) ( 1- 3- ) , (2,2,3).

fooobar.com/questions/705215/...

ind2 , . , np.insert.

np.arange(*ind2[1].indices(3))

: [0,1,2]. .

ind=list(ind2)
ind[1]=np.arange(*ind2[1].indices(3)).reshape(1,-1,1)
A[ind]

, , . , i1.

- , ix_, .

A[np.array([0,1])[None,:,None],:,np.array([0,2])[None,None,:]] # (1,2,2,3)
A[np.array([0,1])[None,:,None],np.array([0,1,2])[:,None,None],np.array([0,2])[None,None,:]]
# (3,2,2)

.

- . . :

A[np.array([0,1])[:,None],:,np.array([0,2])[None,:]].transpose(2,0,1)
# (3,2,2)
A[np.array([0,1])[:,None],:,np.array([0,2])[None,:]].transpose(0,2,1)
# (2, 3, 2)
0

, , , , A (, , ...).

import numpy as np  

def index(A, s):
    ind = []
    groups = s.split(';')
    for i, group in enumerate(groups):
        if group == ":":
            ind.append(range(A.shape[i]))
        else:
            ind.append([int(n) for n in group.split(',')])
    return np.ix_(*ind)

A = np.arange(3*3*3).reshape((3,3,3))

ind2 = index(A,"0,1;:;0,2")
print A[ind2]

def index2(A,s):return np.ix_(*[range(A.shape[i])if g==":"else[int(n)for n in g.split(',')]for i,g in enumerate(s.split(';'))])

ind3 = index2(A,"0,1;:;0,2")
print A[ind3]
0

, , ix_, .

A[ind1]

A[i1][:,i2][:,:,i3]

i2 - ,

A[i1][...,i3]

ind2

A[ind2[0].flatten()][[ind2[2].flatten()]

, j0,j1,j2 , ix_, .

I can imagine circumstances in which it would be convenient to assign A1 = A[i1], and then a lot of action with the participation A1, including, but not limited to A1[...,i3]. You need to know when it A1is a view and when it is a copy.

Another indexing tool is take:

A.take(i0,axis=0).take(i2,axis=2)
0
source

Source: https://habr.com/ru/post/1626006/


All Articles