import numpy as np
def put_at(index, axis=-1, slc=(slice(None),)):
"""Gets the numpy indexer for the given index based on the axis."""
return (axis < 0)*(Ellipsis,) + axis*slc + (index,) + (-1-axis)*slc
def reorder_inplace(array, new_order, axis=0):
"""
Reindex (reorder) the array along an axis.
:param array: The array to reindex.
:param new_order: A list with the new index order. Must be a valid permutation.
:param axis: The axis to reindex.
"""
if np.size(array, axis=axis) != len(new_order):
raise ValueError(
'The new order did not match indexed array along dimension %{0}; '
'dimension is %{1} but corresponding boolean dimension is %{2}'.format(
axis, np.size(array, axis=axis), len(new_order)
)
)
visited = set()
for index, source in enumerate(new_order):
if index not in visited and index != source:
initial_values = np.take(array, index, axis=axis).copy()
destination = index
visited.add(destination)
while source != index:
if source in visited:
raise IndexError(
'The new order is not unique; '
'duplicate found at position %{0} with value %{1}'.format(
destination, source
)
)
array[put_at(destination, axis=axis)] = array.take(source, axis=axis)
destination = source
source = new_order[destination]
visited.add(destination)
array[put_at(destination, axis=axis)] = initial_values
3条答案
按热度按时间ewm0tg9j1#
np.ndarray.sort
是唯一一个声称已经就位的排序,它没有给予您太多的控制权。将顺序索引放在右边是可行的--但可能会给予不可预测的结果。显然,它正在进行某种顺序赋值,而在左边较早的赋值可能会影响右边的值。
要按预期进行这种赋值,需要某种缓冲。
右边的索引绕过了这个问题,但这不是在原处,变量
a
指向一个新对象。然而,使用
[:]
赋值可以解决这个问题:a.data
id是相同的这一事实表明这是一个inplace操作,但是最好用其他索引来测试它,以确保它能做你想要的事情。但是,“inplace”排序是必要的吗?如果数组非常大,可能需要它来避免内存错误。但是我们必须测试替代方法,看看它们是否有效。
inplace
在其他变量使用相同数据时也很重要。使用
a[:]=
时,b
的行将重新排序。a
和b
继续共享同一个data
。使用a=
时,b
不变。a
和b
现在已去耦。0pizxfdo2#
不幸的是,
numpy
没有针对此问题的内置解决方案,唯一的方法是要么使用一些聪明的赋值语句,要么编写自己的自定义方法。使用循环检测、一个用于记忆索引的附加集合和一个用于缓存轴的辅助数组,我为此编写了一个定制方法,该方法对于重排序大型
ndarrays
非常有用:示例:
在轴
0
上重新排序:在轴
1
上重新排序:1000 x 1000
小阵列的时序和存储器对于小阵列,内存消耗没有太大的不同,但
numpy
版本要快得多。20000 x 20000
的时序和存储器当数组的大小增加一个等级时,
numpy
版本的速度会慢很多。numpy
版本的内存消耗也非常高。自定义就地重新排序使用的内存量可以忽略不计。4sup72z83#
给你,
此外,这里有几个'numpy for Matlab用户'的页面,我发现有用的,当我开始:
Link
http://mathesaurus.sourceforge.net/matlab-numpy.html