【问题标题】:Finding the Index of sorted elements in Python Array在 Python 数组中查找已排序元素的索引
【发布时间】:2014-01-07 06:13:36
【问题描述】:

我已经看到问题的答案:
是否可以通过使用元素的索引以降序排列一个 numpy 数组(或 python 列表)?(例如。@987654321 @)

一个非常简洁的答案似乎是(来自上面的链接):

L = array([4, 1, 0, 8, 5, 2])
sorted(range(len(L)), key=lambda i:L[i])

这给出了排序元素的位置(在原始数组中)。

8 --> 3
5 --> 4
4 --> 0
2 --> 5
1 --> 1
0 --> 2

所以答案是:

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

我所追求的是元素的位置(在排序数组中):

L = array([4, 1, 0, 8, 5, 2])

8 --> 0
5 --> 1
4 --> 2
2 --> 3
1 --> 4
0 --> 5

所以我想要:

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

我意识到我可以从第一个例子中得到答案,并用它来获得我想要的东西(稍微摆弄一下)但是有捷径吗?

效率不是问题。我只需要一些能给我答案的东西。

【问题讨论】:

  • 感谢大家的回复。我喜欢使用 lambda 表达式两次来得到我想要的。现在有人可以解释一下(用非常简单的术语来说)那行代码是如何实际操作的,我将不胜感激!

标签: python arrays sorting numpy


【解决方案1】:

你在使用 numpy 吗?如果是这样,请使用numpy.argsort

import numpy as np
fakedata = np.array([40,20,60,50,10,20,80,30,50,40])
sorted_index = np.argsort(fakedata)
print(sorted_index)
print(fakedata[sorted_index])
[4 1 5 7 0 9 3 8 2 6] # sorted index
[10 20 20 30 40 40 50 50 60 80] # values selected by the sorted index

【讨论】:

  • 这是对我的问题第一部分的回答——这个问题已经在别处得到了回答。我想要:对于原始列表中的每个元素,给我它在排序列表中的位置。不是:对于排序列表中的每个元素,给我它在原始列表中的位置。
【解决方案2】:

编辑当我第一次阅读这个问题时,我以为你在寻找numpy.argsort

再读一遍,我发现我看错了。

scipy.stats.rankdata 是您要查找的内容(偏移 1 并反转)

(scipy.stats.rankdata([4, 1, 0, 8, 5, 2])-1)[::-1]
=> array([ 2.,  4.,  5.,  0.,  1.,  3.])

(原来的错误答案,指的是argsort:)

from numpy import array, argsort
L = array([4, 1, 0, 8, 5, 2])
argsort(L)
=> array([2, 1, 5, 0, 4, 3])

【讨论】:

  • 这不是给出错误的答案吗?他想要 [2,4,5,0,1,3] 作为答案?
  • 这是他不想要的第一个版本的事情(但相反)。
  • @PeterdeRivaz 对,我误读了这个问题。我现在修正了我的答案。
  • 您可能想要添加 method='ordinal' 标志。
【解决方案3】:

您可以简单地使用您的技术两次来获取排序列表中的索引:

A=[4, 1, 0, 8, 5, 2]
B=sorted(range(len(A)),key=lambda x:A[x],reverse=True)
C=sorted(range(len(A)),key=lambda x:B[x])
print C

打印

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

说明

想法是第一次迭代产生一个列表:

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

给出排序序列的原始列表中的位置。

换句话说,A[3]=8 是原始列表中最大的元素,A[4]=5 是次大的,以此类推

然后第二阶段将 B 中的这些索引重新排序为 0、1、2、3、4、5 的顺序,并生成包含列表 B 中的索引的 C。

将 B 视为将列表按降序排序,将 C 视为将排序反转回原始未排序的顺序,同时跟踪已排序列表中的索引,这可能会有所帮助。

【讨论】:

  • 也许我说得太早了?好的:A=[4, 1, 0, 8, 5, 2] 试过 A=[14, 15, 30, 18, 11, 21]
  • @RustyC 你说得对,我已经编辑了答案以表现得​​更好
猜你喜欢
  • 2021-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-09
  • 2017-12-01
  • 2013-08-26
  • 2015-08-19
  • 2020-11-28
相关资源
最近更新 更多