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?
source to share
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.
source to share
Here you,
a = a[:, :, new_order]
Also, here are a couple of "numpy for Matlab user pages" that I found helpful when I started:
source to share