python:对一系列元素的列表列表进行排序

时间:2016-03-30 00:54:12

标签: python list sorting numpy range

我现在正在努力解决这个问题,但是我无法解决这个问题。

我有一个列表列表,其中每个列表包含0到5之间的值:

[[ 0.  0.  4.  2.  2.  2.  2.  2.  2.  2.]
 [ 0.  0.  1.  2.  3.  3.  3.  3.  3.  3.]
 [ 0.  0.  2.  3.  4.  4.  1.  2.  1.  2.]
 [ 0.  0.  3.  4.  5.  1.  4.  4.  5.  5.]
 ...
 [ 0.  0.  5.  3.  3.  3.  4.  3.  4.  3.]
 [ 0.  0.  3.  4.  1.  1.  1.  1.  4.  4.]
 [ 0.  0.  3.  4.  1.  3.  3.  3.  3.  1.]
 [ 0.  0.  1.  4.  4.  5.  3.  4.  3.  1.]]

现在我想从最后一个元素开始对这个列表进行排序,然后是最后一个元素,一直到开头,得到类似的东西:

[[ 0.  0.  3.  4.  1.  3.  3.  3.  3.  1.]
 [ 0.  0.  1.  4.  4.  5.  3.  4.  3.  1.]
 [ 0.  0.  5.  3.  3.  3.  3.  3.  4.  1.]
 [ 0.  0.  2.  3.  4.  4.  1.  2.  1.  2.]
 ...
 [ 0.  0.  3.  4.  1.  1.  1.  1.  4.  4.]
 [ 0.  0.  3.  3.  3.  4.  4.  4.  4.  4.]
 [ 0.  0.  4.  4.  3.  4.  5.  5.  1.  5.]
 [ 0.  0.  3.  4.  5.  1.  4.  4.  5.  5.]]

我在网上找到的排序数组/列表问题的所有回复都涉及不同的列/元素,而我无法使这一系列元素起作用。最终唯一有效的解决方案是:

array = array[np.lexsort((array[:,-9], array[:,-8], array[:,-7], array[:,-6], array[:,-5], array[:,-4], array[:,-3], array[:,-2], array[:,-1]))]

这不仅非常难看,而且也不是很灵活。任何用循环或变量替换此命令的尝试都会失败。

非常感谢任何建议!

3 个答案:

答案 0 :(得分:2)

假设:

LoL=[[ 0.,  0.,  4.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,],
 [ 0.,  0.,  1.,  2.,  3.,  3.,  3.,  3.,  3.,  3.,],
 [ 0.,  0.,  2.,  3.,  4.,  4.,  1.,  2.,  1.,  2.,],
 [ 0.,  0.,  3.,  4.,  5.,  1.,  4.,  4.,  5.,  5.,],
 [ 0.,  0.,  5.,  3.,  3.,  3.,  4.,  3.,  4.,  3.,],
 [ 0.,  0.,  3.,  4.,  1.,  1.,  1.,  1.,  4.,  4.,],
 [ 0.,  0.,  3.,  4.,  1.,  3.,  3.,  3.,  3.,  1.,],
 [ 0.,  0.,  1.,  4.,  4.,  5.,  3.,  4.,  3.,  1.,]]

使用按键功能:

>>> sorted(LoL, key=lambda l: l[::-1])
[[0.0, 0.0, 3.0, 4.0, 1.0, 3.0, 3.0, 3.0, 3.0, 1.0], 
 [0.0, 0.0, 1.0, 4.0, 4.0, 5.0, 3.0, 4.0, 3.0, 1.0], 
 [0.0, 0.0, 2.0, 3.0, 4.0, 4.0, 1.0, 2.0, 1.0, 2.0], 
 [0.0, 0.0, 4.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0], 
 [0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0], 
 [0.0, 0.0, 5.0, 3.0, 3.0, 3.0, 4.0, 3.0, 4.0, 3.0], 
 [0.0, 0.0, 3.0, 4.0, 1.0, 1.0, 1.0, 1.0, 4.0, 4.0], 
 [0.0, 0.0, 3.0, 4.0, 5.0, 1.0, 4.0, 4.0, 5.0, 5.0]]

如果这些是numpy数组,请使用ndarray.sort:

>>> m=np.matrix(LoL)
>>> m
array([[ 0.,  0.,  4.,  2.,  2.,  2.,  2.,  2.,  2.,  2.],
       [ 0.,  0.,  1.,  2.,  3.,  3.,  3.,  3.,  3.,  3.],
       [ 0.,  0.,  2.,  3.,  4.,  4.,  1.,  2.,  1.,  2.],
       [ 0.,  0.,  3.,  4.,  5.,  1.,  4.,  4.,  5.,  5.],
       [ 0.,  0.,  5.,  3.,  3.,  3.,  4.,  3.,  4.,  3.],
       [ 0.,  0.,  3.,  4.,  1.,  1.,  1.,  1.,  4.,  4.],
       [ 0.,  0.,  3.,  4.,  1.,  3.,  3.,  3.,  3.,  1.],
       [ 0.,  0.,  1.,  4.,  4.,  5.,  3.,  4.,  3.,  1.]])
>>> m[m[:,-1].argsort()]
array([[ 0.,  0.,  3.,  4.,  1.,  3.,  3.,  3.,  3.,  1.],
       [ 0.,  0.,  1.,  4.,  4.,  5.,  3.,  4.,  3.,  1.],
       [ 0.,  0.,  4.,  2.,  2.,  2.,  2.,  2.,  2.,  2.],
       [ 0.,  0.,  2.,  3.,  4.,  4.,  1.,  2.,  1.,  2.],
       [ 0.,  0.,  1.,  2.,  3.,  3.,  3.,  3.,  3.,  3.],
       [ 0.,  0.,  5.,  3.,  3.,  3.,  4.,  3.,  4.,  3.],
       [ 0.,  0.,  3.,  4.,  1.,  1.,  1.,  1.,  4.,  4.],
       [ 0.,  0.,  3.,  4.,  5.,  1.,  4.,  4.,  5.,  5.]])

答案 1 :(得分:2)

您可以简单地转置输入数组,然后使用np.lexsort获取矢量化的排序索引,从而获得非常有效的解决方案,如此 -

array[np.lexsort(array[:,1:].T)]

示例运行 -

In [128]: # Random array of integers
     ...: array = np.random.randint(0,9,(5,10))
     ...: 
     ...: # Original method
     ...: A = ((array[:,-9], array[:,-8], array[:,-7], array[:,-6], array[:,-5], \
     ...:       array[:,-4], array[:,-3], array[:,-2], array[:,-1]))
     ...: out_loopy = array[np.lexsort(A)]
     ...: 
     ...: # Vectorized method
     ...: out_vectorized = array[np.lexsort(array[:,1:].T)]
     ...: 

In [129]: np.allclose(out_loopy,out_vectorized)
Out[129]: True

答案 2 :(得分:0)

使用以下排序功能

def mysort(list1,list2):
  i = min(len(list1),len(list2))-1  # in case unequal lines
  while (i>0) and list1[i]== list2[i]:
    i -= 1
  return cmp(list1[i],list2[i])

测试(打印正确答案)

LL = [[ 0,  0,  4,  2,  2,  2,  2,  2,  2,  2,],
 [ 0,  0,  1,  2,  3,  3,  3,  3,  3,  3,],
 [ 0,  0,  2,  3,  4,  4,  1,  2,  1,  2,],
 [ 0,  0,  3,  4,  5,  1,  4,  4,  5,  5,],
 [ 0,  0,  5,  3,  3,  3,  4,  3,  4,  3,],
 [ 0,  0,  3,  4,  1,  1,  1,  1,  4,  4,],
 [ 0,  0,  3,  4,  1,  3,  3,  3,  3,  1,],
 [ 0,  0,  1,  4,  4,  5,  3,  4,  3,  1,]]

LL.sort(mysort)
print (LL)