There are some questions that come close, but I haven't found a specific answer to this. I'm trying to do some in-place sorting of a numpy 3D array along a given axis. I don't want simple sorting though, I want to resort the array according to my own index. For example
a = np.random.rand((3,3,3))
and let's say I want to resort the last dimension according to the following indices of the old array:
new_order = [1,2,0]
I would expect to be able to say:
a[:,:,new_order] = a
but this does not behave as expected. Suggestions?
np.ndarray.sort
is the only sort that claims to be inplace, and it does not give you much control.
Placing the order index on the right works - but can give unpredictable results. Evidently it is doing some sort of sequential assignment, and an earlier assignment on the left can affect 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]])
To do this sort of assignment predictably requires some sort of buffering.
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 of the right gets around this, but this is not in-place. The variable a
points to a 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 assignment with [:]
may solve this:
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 a.data
id is the same indicates that this is an inplace action. But it would be good to test this with other indexing to make sure it does what you want.
But, is 'inplace' sorting necessary? If the array is very large it might be needed to avoid memory errors. But we'd have to test the alternatives to see if they work.
inplace
matters also if there is some other variable that uses the same data. For example
b = a.T # a transpose
With a[:]=
the rows of b
will be reordered. a
and b
continue to share the same data
. With a=
, b
is unchanged. a
and b
are now decoupled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With