Sort an array in place according to a given index

There are several questions that are close, but I have not found a specific answer to this question. I am trying to do some sort of local sorting of a massive 3D array along a given axis. I don't want a simple sort, though, I want to resort to an array according to my own index. for example

a = np.random.rand((3,3,3))

      

and let's say that I want to apply the last dimension according to the following indices of the old array:

new_order = [1,2,0]

      

I expect to be able to say:

a[:,:,new_order] = a

      

but this is not as expected. Suggestions?

+3


source to share


2 answers


np.ndarray.sort

is the only type that claims to be in place and doesn't give you much control.

Placing the order index on the right works but can give unpredictable results. Obviously it does some sort of sequential assignment, and an earlier assignment on the left may affect the values ​​on the right.

In [719]: a=np.arange(12).reshape(3,4)
In [720]: a[:,[0,1,3,2]]=a
In [721]: a
Out[721]: 
array([[ 0,  1,  2,  2],
       [ 4,  5,  6,  6],
       [ 8,  9, 10, 10]])

      

Some buffering is predictably required to perform this kind of assignment.

In [728]: a[:,[0,1,3,2]]=a.copy()
In [729]: a
Out[729]: 
array([[ 0,  1,  3,  2],
       [ 4,  5,  7,  6],
       [ 8,  9, 11, 10]])

      

Indexing right turns around this, but it's out of place. The variable a

points to the new object.

In [731]: a=a[:,[0,1,3,2]]
In [732]: a
Out[732]: 
array([[ 0,  1,  3,  2],
       [ 4,  5,  7,  6],
       [ 8,  9, 11, 10]])

      



However, assigning with help [:]

might solve the following:

In [738]: a=np.arange(12).reshape(3,4)
In [739]: a.__array_interface__
Out[739]: 
{'data': (181868592, False),   # 181... is the id of the data buffer
 'descr': [('', '<i4')],
 'shape': (3, 4),
 'strides': None,
 'typestr': '<i4',
 'version': 3}
In [740]: a[:]=a[:,[0,1,3,2]]
In [741]: a.__array_interface__
Out[741]: 
{'data': (181868592, False),  # same data buffer
 'descr': [('', '<i4')],
 'shape': (3, 4),
 'strides': None,
 'typestr': '<i4',
 'version': 3}
In [742]: a
Out[742]: 
array([[ 0,  1,  3,  2],
       [ 4,  5,  7,  6],
       [ 8,  9, 11, 10]])

      

The fact that the id is a.data

the same indicates that this is an inplace action. But it would be nice to test this with other indexers to make sure it does what you want.

But is the 'inplace' sort necessary? If the array is very large, you may need it to avoid memory errors. But we need to test the alternatives to see if they work.

inplace

matters if there is another variable that uses the same data. for example

b = a.T # a transpose

      

The a[:]=

lines b

will be reordered. a

and b

continue to share the same data

. C a=

, b

does not change. a

and are b

now untied.

+5


source


Here you,

a = a[:, :, new_order]

      

Also, here are a couple of "numpy for Matlab user pages" that I found helpful when I started:



http://wiki.scipy.org/NumPy_for_Matlab_Users

http://mathesaurus.sourceforge.net/matlab-numpy.html

0


source







All Articles