python - 根据给定索引就地 numpy 数组排序

标签 python numpy

有些问题很接近,但我还没有找到具体的答案。我正在尝试沿给定轴对 numpy 3D 数组进行一些就地排序。我不想简单排序,我想根据我自己的索引对数组进行排序。例如

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

假设我想根据旧数组的以下索引求出最后一个维度:

new_order = [1,2,0]

我希望能够说:

a[:,:,new_order] = a

但这并不像预期的那样表现。有什么建议吗?

最佳答案

np.ndarray.sort 是唯一一种声称就地排序的方法,它不会给您太多控制权。

将顺序索引放在右边是可行的 - 但可能会产生不可预知的结果。显然,它正在进行某种顺序赋值,左侧较早的赋值会影响右侧的值。

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]])

要进行这种可预测的分配,需要某种缓冲。

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]])

右侧的索引绕过了这个问题,但这不是就地的。变量 a 指向一个新对象。

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]])

但是用 [:] 赋值可能会解决这个问题:

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]])

a.data id 相同的事实表明这是一个就地操作。但最好用其他索引对此进行测试,以确保它符合您的要求。

但是,“就地”排序是否必要?如果数组非常大,可能需要避免内存错误。但我们必须测试替代方案以查看它们是否有效。

inplace 如果有一些其他变量使用相同的数据也很重要。例如

b = a.T # a transpose

a[:]= b 的行将被重新排序。 ab 继续共享相同的 data。对于 a=b 不变。 ab 现在解耦了。

关于python - 根据给定索引就地 numpy 数组排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26239802/

相关文章:

python - 为什么重写 save() 方法会被绕过?

python - 在 python 3 中,如何将数据从二维数组传输到 csv 文本文件

python - 如何从 pandas 数据帧创建多级嵌套字典?

python - 计算大数组内某些数组的平均值

python - 我如何获得掩码,反转 numpy.flatnonzero?

python - Python 新手,不知道我的代码有什么问题

python - 从数组的数组中提取数组

python - Numpy 数组占用太多内存

python - 在 Django 中按非字段过滤

python - Django 1.9 如何在 __init__.py 中导入