2014-10-07 68 views
2

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

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

,让说,我想根据旧阵列的以下指标诉诸的最后一个维度:

new_order = [1,2,0] 

我会希望能够说:

a[:,:,new_order] = a 

但这并不像预期的那样。建议?

+2

你在找'a = a [:,:,new_order]'吗? – farenorth 2014-10-07 15:47:04

+0

这已经很久了,我忘了你可以在Matlab中做到这一点。 – farenorth 2014-10-07 17:00:21

回答

4

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分离。

相关问题