如何在Python中反转和转发NumPy 2D数组?

时间:2015-04-03 10:57:27

标签: python arrays sorting numpy

我有以下表格的数据:

#---------------------
# Data
#---------------------
p   q   r
2   8   14
2   9   22
1   5   19
2   7   19
3   11  13
2   7   20
1   4   15
3   12  17
1   4   14
1   5   20
2   7   17
3   10  13
3   11  20
3   11  14
1   6   18
3   12  16
2   9   21
3   10  19
2   8   13
1   6   22
1   4   13
2   8   15
3   12  15
3   10  16
2   9   16
1   5   16
1   6   21

现在我需要使用NumPy以下列方式对这些数据进行排序:

  1. 列p。
  2. 的升序
  3. 第q列的升序。
  4. 列r。降序。
  5. 我使用了以下代码,但它没有正确排序:

    import numpy as np
    
    data = open('data.dat', "r")
    line = data.readline()
    while line.startswith('#'):
        line = data.readline()
    data_header = line.split("\t")
    data_header[-1] = data_header[-1].strip()
    
    _data_ = np.genfromtxt(data, comments='#', delimiter='\t', names = data_header, dtype = None, unpack = True).transpose()            # Read space-separated values in engine data file.
    sorted_index =  np.lexsort((_data_['r'][::-1], _data_['q'], _data_['p']))
    _data_ =  _data_[sorted_index]
    print (_data_)
    

    Ouptut

    1   4   15
    1   4   14
    1   4   13
    1   5   19
    1   5   20
    1   5   16
    1   6   21
    1   6   22
    1   6   18
    2   7   20
    2   7   19
    2   7   17
    2   8   13
    2   8   15
    2   8   14
    2   9   22
    2   9   21
    2   9   16
    3   10  13
    3   10  16
    3   10  19
    3   11  14
    3   11  13
    3   11  20
    3   12  16
    3   12  15
    3   12  17
    

    这种排序方法可能有什么问题?

2 个答案:

答案 0 :(得分:0)

问题是,当您撤销r列时,numpy并不知道您的指数会发生变化。 解决方法分两步进行,但它不会优雅:

pre_sort_index = np.lexsort((_data_['r'],), axis=0)[::-1]
sorted_index =  np.lexsort((_data_[pre_sort_index]['q'], _data_[pre_sort_index]['p']))
_data_ =  _data_[pre_sort_index][sorted_index]

答案 1 :(得分:0)

实际上,您快到了!只需在代码中修改这一行(减号而不是[::-1])就可以了

sorted_index =  np.lexsort((-_data_['r'], _data_['q'], _data_['p']))

更一般地讲,这个减号有点可笑,但只要您只处理数字值,它就应该起作用

# 2D array will be sorted first by p, then by q (if p is the same), then by r
sortkeys = ['p','q','r']
# 1 is ascending/forward sort, -1 is descending/reverse sort
sortdirection = [1,1,-1]
# need [::-1] as its sorts with last element first...
ind = np.lexsort(tuple([(_data_[skey])*sdir for skey,sdir in
                                     zip(sortkeys[::-1],sortdirection[::-1])]))
_data_ = _data_[ind]
for i in _data_:
    print(i)

输出:

(1, 4, 15)
(1, 4, 14)
(1, 4, 13)
(1, 5, 20)
(1, 5, 19)
(1, 5, 16)
(1, 6, 22)
(1, 6, 21)
(1, 6, 18)
(2, 7, 20)
(2, 7, 19)
(2, 7, 17)
(2, 8, 15)
(2, 8, 14)
(2, 8, 13)
(2, 9, 22)
(2, 9, 21)
(2, 9, 16)
(3, 10, 19)
(3, 10, 16)
(3, 10, 13)
(3, 11, 20)
(3, 11, 14)
(3, 11, 13)
(3, 12, 17)
(3, 12, 16)
(3, 12, 15)