如何在Python中按行对2D数组进行排序?

23

我有一个二维数组,维度为3x10,我想按照第二行的值从小到大对其进行排序。

5个回答

43
你的“二维数组”是什么样子?
例如:
>>> a = [
     [12, 18, 6, 3], 
     [ 4,  3, 1, 2], 
     [15,  8, 9, 6]
]
>>> a.sort(key=lambda x: x[1])
>>> a
[[4,  3,  1, 2], 
 [15, 8,  9, 6], 
 [12, 18, 6, 3]]

但我猜你想要这样的东西:

>>> a = [
     [12, 18, 6, 3], 
     [ 4,  3, 1, 2], 
     [15,  8, 9, 6]
]
>>> a = zip(*a)
>>> a.sort(key=lambda x: x[1])
>>> a
[(6,  1,  9), 
 (3,  2,  6), 
 (18, 3,  8), 
 (12, 4, 15)]
>>> a = zip(*a)
>>> a
[(6, 3, 18, 12), 
 (1, 2,  3,  4), 
 (9, 6,  8, 15)
]

1
考虑使用 itemgetter(1) 替代 lambda - John La Rooy

22

Python本身并没有"2d数组"——它有(1d)内置列表和标准库模块array中的(1d)数组。第三方库,如numpy提供了适用于Python的多维数组,但如果你使用了其中一些,当然会提到这样的第三方库,而不仅仅是说"在Python中",对吧?-)

因此,我假设您所说的"2d数组"是指一个列表嵌套列表,例如:

lol = [ range(10), range(2, 12), range(5, 15) ]
或类似的东西——即一个包含3个项目的列表,每个项目都是一个包含10个项目的列表,而“第二行”将是子列表项 lol [1]。是的,有很多假设,但你的问题太模糊了,无论如何都无法避免做出假设 - 如果您不喜欢人们试图读懂您的想法(并可能会失败),请编辑您的问题以更加精确地说明,并提供一个示例!

因此,在这些假设下,您可以对每个3个子列表按照需要对第二个子列表进行排序,例如:

indices = range(10)
indices.sort(key = lol[1].__getitem__)
for i, sublist in enumerate(lol):
  lol[i] = [sublist[j] for j in indices]

这里的一般方法是对索引范围进行排序,然后只需使用适当排序的范围来重新排列所有相关子列表。

如果您实际上有不同的问题,那么当然会有不同的解决方案;-)。


谢谢,你真的是一个很好的心灵读者:)))),将来我会更加描述和决定性...我的“真正问题”是关于按照第二个所需顺序对子列表进行排序。 - user257522

11

与其使用lambda x: x[1],你可以使用operator.itemgetter作为sort或sorted函数的键。itemgetter(n)创建一个从列表中获取第n个元素的函数。

>>> matrix = [ [4,5,6], [1,2,3], [7,0,9]]
>>> from operator import itemgetter
>>> sorted(matrix, key=itemgetter(1))
[[7, 0, 9], [1, 2, 3], [4, 5, 6]]

1

如果你在谈论标准的Python列表,那么这很容易:mylist[1].sort()。例如:

>>> from random import randint
>>> a_list = [[randint(1,15) for _ in range(10)] for _ in range(3)]
>>> print a_list
[[3, 12, 3, 12, 13, 5, 12, 2, 1, 13], [3, 8, 7, 4, 6, 11, 15, 12, 4, 6], [15, 3, 8, 15, 1, 6, 4, 7, 15, 14]]
>>> a_list[1].sort()
>>> print a_list
[[3, 12, 3, 12, 13, 5, 12, 2, 1, 13], [3, 4, 4, 6, 6, 7, 8, 11, 12, 15], [15, 3, 8, 15, 1, 6, 4, 7, 15, 14]]

0
这是我为此目的编写的一个小函数:
def sorted_table(data, column=0, reverse=False):
    return sorted(data, cmp=lambda a,b: cmp(a[column], b[column]), reverse=reverse)

实际上,我有一个稍微复杂一点的需求,就是要按照两个列对表格进行排序。事实证明,cmp()函数非常灵活; 这是我的原始函数:
def sort_report(data):
    """Sort report columns: first by value, then by label."""
    return sorted(data, cmp=lambda a,b: cmp(b[2], a[2]) or cmp(a[0], b[0])) # label is column 0; value is column 2

在第一个案例中,b和a被颠倒了,因为目标是将值从高到低排序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接