按列对 NumPy 中的数组进行排序

2024-12-13 08:36:00
admin
原创
146
摘要:问题描述:如何按第 n 列对 NumPy 数组进行排序?例如,给定:a = array([[9, 2, 3], [4, 5, 6], [7, 0, 5]]) 我想a按第二列对行进行排序以获得:array([[7, 0, 5], [9, 2, 3], ...

问题描述:

如何按第 n 列对 NumPy 数组进行排序?

例如,给定:

a = array([[9, 2, 3],
           [4, 5, 6],
           [7, 0, 5]])

我想a按第二列对行进行排序以获得:

array([[7, 0, 5],
       [9, 2, 3],
       [4, 5, 6]])

解决方案 1:

按第二列排序a

a[a[:, 1].argsort()]

解决方案 2:

@steve的回答实际上是最优雅的方式。

对于“正确”的方法,请参见numpy.ndarray.sort的 order 关键字参数

但是,您需要将数组视为带有字段的数组(结构化数组)。

如果您最初没有使用字段定义数组,那么“正确”的方法就相当丑陋......

举一个简单的例子,对其进行排序并返回一份副本:

In [1]: import numpy as np

In [2]: a = np.array([[1,2,3],[4,5,6],[0,0,1]])

In [3]: np.sort(a.view('i8,i8,i8'), order=['f1'], axis=0).view(np.int)
Out[3]: 
array([[0, 0, 1],
       [1, 2, 3],
       [4, 5, 6]])

就地排序:

In [6]: a.view('i8,i8,i8').sort(order=['f1'], axis=0) #<-- returns None

In [7]: a
Out[7]: 
array([[0, 0, 1],
       [1, 2, 3],
       [4, 5, 6]])

据我所知,@Steve 的方法确实是最优雅的......

此方法的唯一优点是“order”参数是用于对搜索进行排序的字段列表。例如,您可以通过提供 order=['f1','f2','f0'] 来按第二列、第三列、第一列进行排序。

解决方案 3:

您可以按照 Steve Tjoa 的方法对多个列进行排序,方法是使用类似合并排序的稳定排序,并按从最不重要到最重要的列对索引进行排序:

a = a[a[:,2].argsort()] # First sort doesn't need to be stable.
a = a[a[:,1].argsort(kind='mergesort')]
a = a[a[:,0].argsort(kind='mergesort')]

这将按第 0 列、第 1 列、第 2 列排序。

解决方案 4:

如果有人想在程序的关键部分使用排序,这里是不同提案的性能比较:

import numpy as np
table = np.random.rand(5000, 10)

%timeit table.view('f8,f8,f8,f8,f8,f8,f8,f8,f8,f8').sort(order=['f9'], axis=0)
1000 loops, best of 3: 1.88 ms per loop

%timeit table[table[:,9].argsort()]
10000 loops, best of 3: 180 µs per loop

import pandas as pd
df = pd.DataFrame(table)
%timeit df.sort_values(9, ascending=True)
1000 loops, best of 3: 400 µs per loop

因此,看起来使用argsort进行索引是迄今为止最快的方法......

解决方案 5:

来自NumPy 邮件列表,这是另一种解决方案:

>>> a
array([[1, 2],
       [0, 0],
       [1, 0],
       [0, 2],
       [2, 1],
       [1, 0],
       [1, 0],
       [0, 0],
       [1, 0],
      [2, 2]])
>>> a[np.lexsort(np.fliplr(a).T)]
array([[0, 0],
       [0, 0],
       [0, 2],
       [1, 0],
       [1, 0],
       [1, 0],
       [1, 0],
       [1, 2],
       [2, 1],
       [2, 2]])

解决方案 6:

正如Python 文档 wiki建议的那样:

a = ([[1, 2, 3], [4, 5, 6], [0, 0, 1]]); 
a = sorted(a, key=lambda a_entry: a_entry[1]) 
print a

输出:

[[[0, 0, 1], [1, 2, 3], [4, 5, 6]]]

解决方案 7:

我遇到了类似的问题。

我的问题:

我想计算 SVD,需要按降序对特征值进行排序。但我想保留特征值和特征向量之间的映射。我的特征值在第一行,而其下方的相应特征向量在同一列中。

所以我想按第一行按降序对二维数组进行逐列排序。

我的解决方案

a = a[::, a[0,].argsort()[::-1]]

那么这是如何实现的呢?

a[0,]只是我想要排序的第一行。

现在我使用 argsort 来获取索引的顺序。

我使用[::-1]是因为我需要降序。

最后我用它a[::, ...]来获取按正确顺序排列的视图。

解决方案 8:

import numpy as np
a=np.array([[21,20,19,18,17],[16,15,14,13,12],[11,10,9,8,7],[6,5,4,3,2]])
y=np.argsort(a[:,2],kind='mergesort')# a[:,2]=[19,14,9,4]
a=a[y]
print(a)

期望输出是[[6,5,4,3,2],[11,10,9,8,7],[16,15,14,13,12],[21,20,19,18,17]]

请注意,argsort(numArray)返回的索引numArray应该按排序的方式排列。

例子

x=np.array([8,1,5]) 
z=np.argsort(x) #[1,3,0] are the **indices of the predicted sorted array**
print(x[z]) #boolean indexing which sorts the array on basis of indices saved in z

答案是[1,5,8]

解决方案 9:

稍微复杂一点的lexsort例子 - 第一列降序排列,第二列升序排列。 的诀窍lexsort是按行排序(因此有.T),并优先考虑最后一行。

In [120]: b=np.array([[1,2,1],[3,1,2],[1,1,3],[2,3,4],[3,2,5],[2,1,6]])
In [121]: b
Out[121]: 
array([[1, 2, 1],
       [3, 1, 2],
       [1, 1, 3],
       [2, 3, 4],
       [3, 2, 5],
       [2, 1, 6]])
In [122]: b[np.lexsort(([1,-1]*b[:,[1,0]]).T)]
Out[122]: 
array([[3, 1, 2],
       [3, 2, 5],
       [2, 1, 6],
       [2, 3, 4],
       [1, 1, 3],
       [1, 2, 1]])

解决方案 10:

熊猫方法只是为了完整性:

a = np.array([[9, 2, 3],
              [4, 5, 6],
              [7, 0, 5]])              
a = pd.DataFrame(a) 

             
a.sort_values(1, ascending=True).to_numpy()
array([[7, 0, 5], # '1' means sort by second column
       [9, 2, 3],
       [4, 5, 6]])

prl900
进行了基准测试,并与接受的答案进行了比较:

%timeit pandas_df.sort_values(9, ascending=True)
1000 loops, best of 3: 400 µs per loop

%timeit numpy_table[numpy_table[:,9].argsort()]
10000 loops, best of 3: 180 µs per loop  

解决方案 11:

这是考虑所有列的另一种解决方案( JJ答案的更紧凑方式);

ar=np.array([[0, 0, 0, 1],
             [1, 0, 1, 0],
             [0, 1, 0, 0],
             [1, 0, 0, 1],
             [0, 0, 1, 0],
             [1, 1, 0, 0]])

使用 lexsort 进行排序,

ar[np.lexsort(([ar[:, i] for i in range(ar.shape[1]-1, -1, -1)]))]

输出:

array([[0, 0, 0, 1],
       [0, 0, 1, 0],
       [0, 1, 0, 0],
       [1, 0, 0, 1],
       [1, 0, 1, 0],
       [1, 1, 0, 0]])

解决方案 12:

这是一个老问题,但如果您需要将其推广到高于 2 维的数组,那么这里有一个可以轻松推广的解决方案:

np.einsum('ij->ij', a[a[:,1].argsort(),:])

对于二维来说,这有点过头了,a[a[:,1].argsort()]根据@steve的回答,这已经足够了,但是这个答案不能推广到更高的维度。你可以在这个问题中找到一个3D数组的例子。

输出:

[[7 0 5]
 [9 2 3]
 [4 5 6]]

解决方案 13:

按第 1 列排序

indexofsort=np.argsort(dataset[:,0],axis=-1,kind='stable') 
dataset   = dataset[indexofsort,:]

解决方案 14:

def sort_np_array(x, column=None, flip=False):
    x = x[np.argsort(x[:, column])]
    if flip:
        x = np.flip(x, axis=0)
    return x

原题中的数组:

a = np.array([[9, 2, 3],
              [4, 5, 6],
              [7, 0, 5]])

sort_np_array问题作者预期的函数结果如下:

sort_np_array(a, column=1, flip=False)
[2]: array([[7, 0, 5],
            [9, 2, 3],
            [4, 5, 6]])

解决方案 15:

感谢这篇文章:https://stackoverflow.com/a/5204280/13890678

我使用结构化数组找到了更“通用”的答案。我认为这种方法的一个优点是代码更易于阅读。

import numpy as np
a = np.array([[9, 2, 3],
           [4, 5, 6],
           [7, 0, 5]])

struct_a = np.core.records.fromarrays(
    a.transpose(), names="col1, col2, col3", formats="i8, i8, i8"
)
struct_a.sort(order="col2")

print(struct_a)
[(7, 0, 5) (9, 2, 3) (4, 5, 6)]

解决方案 16:

只需使用排序,使用您想要排序的列号。

a = np.array([1,1], [1,-1], [-1,1], [-1,-1]])
print (a)
a = a.tolist() 
a = np.array(sorted(a, key=lambda a_entry: a_entry[0]))
print (a)
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用