【问题标题】:numpy structured array sorting by multiple columnsnumpy 结构化数组按多列排序
【发布时间】:2020-05-20 06:52:06
【问题描述】:

一个最小的 numpy 结构化数组生成器:

import numpy as np

index = np.arange(4)
A = np.stack((np.sin(index), np.cos(index)),axis=1)
B = np.eye(4).astype(int)
C = np.array([1, 0, 1, 0], dtype=bool)
goodies = [(a, b, c, d) for a, b, c, d in zip(index, A, B, C)]
dt = [('index', 'int'), ('two_floats', 'float', 2), 
      ('four_ints', 'int', 4), ('and_a_bool', 'bool')]
s = np.array(goodies, dtype=dt)

生成最小的 numpy 结构化数组:

array([(0, [ 0.        ,  1.        ], [1, 0, 0, 0],  True),
       (1, [ 0.84147098,  0.54030231], [0, 1, 0, 0], False),
       (2, [ 0.90929743, -0.41614684], [0, 0, 1, 0],  True),
       (3, [ 0.14112001, -0.9899925 ], [0, 0, 0, 1], False)],
      dtype=[('index', '<i8'), ('two_floats', '<f8', (2,)), ('four_ints', '<i8', (4,)), ('and_a_bool', '?')])

我想先按and_a_bool降序排序,然后按two_floats升序第二列排序,这样输出就可以了然后是

array([(2, [ 0.90929743, -0.41614684], [0, 0, 1, 0],  True),
       (0, [ 0.        ,  1.        ], [1, 0, 0, 0],  True),
       (3, [ 0.14112001, -0.9899925 ], [0, 0, 0, 1], False),
       (1, [ 0.84147098,  0.54030231], [0, 1, 0, 0], False)],
      dtype=[('index', '<i8'), ('two_floats', '<f8', (2,)), ('four_ints', '<i8', (4,)), ('and_a_bool', '?')])

this answer 中提到了np.lexsort,但我不知道如何在此处应用。

我正在寻找使用现有 numpy 方法而不是专门代码的东西。我的数组不会很大,所以我对就地排序或生成新数组没有强烈的偏好,

【问题讨论】:

  • np.sort 采用order 参数,可让您指定要排序的字段和顺序(实际上是对lexsort 的改进)。要获得降序排序,请使用否定字段创建一个新数组,并使用np.argsort 获得所需的排序顺序。
  • @hpaulj 希望可以基于此编写答案。我也去看看,谢谢!
  • @hpaulj 我无法完成这项工作,您可以考虑发布一个简短的答案吗?谢谢!

标签: python python-3.x numpy sorting structured-array


【解决方案1】:

制作一个temp排序数组:

In [133]: temp=np.zeros(s.shape, dtype='bool,float')                                     
In [134]: temp['f0']=~s['and_a_bool']                                                    
In [135]: temp['f1']=s['two_floats'][:,1]                                                
In [136]: temp                                                                           
Out[136]: 
array([(False,  1.        ), ( True,  0.54030231), (False, -0.41614684),
       ( True, -0.9899925 )], dtype=[('f0', '?'), ('f1', '<f8')])

现在argsort(不需要指定order,因为我按所需顺序选择了temp字段):

In [137]: np.argsort(temp)                                                               
Out[137]: array([2, 0, 3, 1])

并将该排序应用于s:

In [138]: s[_137]                                                                        
Out[138]: 
array([(2, [ 0.90929743, -0.41614684], [0, 0, 1, 0],  True),
       (0, [ 0.        ,  1.        ], [1, 0, 0, 0],  True),
       (3, [ 0.14112001, -0.9899925 ], [0, 0, 0, 1], False),
       (1, [ 0.84147098,  0.54030231], [0, 1, 0, 0], False)],
      dtype=[('index', '<i8'), ('two_floats', '<f8', (2,)), ('four_ints', '<i8', (4,)), ('and_a_bool', '?')])

【讨论】:

  • 好吧,这很好用,虽然我现在不明白究竟如何,你对 numpy 的洞察力总是令人震惊!只是第一行对我来说已经没有意义了;打印 temp 时,数据与 dtype 不匹配,但这似乎是使它起作用的原因。谢谢!
猜你喜欢
  • 2019-08-24
  • 2019-03-04
  • 2021-05-18
  • 2015-11-30
  • 1970-01-01
  • 2021-12-18
  • 2011-10-11
  • 2019-05-08
  • 1970-01-01
相关资源
最近更新 更多