Numpy argsort - 它在做什么?

时间:2013-07-27 18:44:56

标签: python numpy

为什么numpy会给出这个结果:

x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()

>[2 3 1 0]

当我期望它这样做时:

  

[3 2 0 1]

显然我对这个功能的理解很缺乏。

9 个答案:

答案 0 :(得分:109)

根据the documentation

  

返回对数组进行排序的索引。

  • 20.0
  • 的索引
  • 30.1
  • 的索引
  • 11.41
  • 的索引
  • 01.48
  • 的索引

答案 1 :(得分:32)

[2, 3, 1, 0]表示最小元素在索引2处,下一个在索引3处最小,然后是索引1,然后是索引0。

a number of ways来获得您正在寻找的结果:

import numpy as np
import scipy.stats as stats

def using_indexed_assignment(x):
    "https://stackoverflow.com/a/5284703/190597 (Sven Marnach)"
    result = np.empty(len(x), dtype=int)
    temp = x.argsort()
    result[temp] = np.arange(len(x))
    return result

def using_rankdata(x):
    return stats.rankdata(x)-1

def using_argsort_twice(x):
    "https://stackoverflow.com/a/6266510/190597 (k.rooijers)"
    return np.argsort(np.argsort(x))

def using_digitize(x):
    unique_vals, index = np.unique(x, return_inverse=True)
    return np.digitize(x, bins=unique_vals) - 1

例如,

In [72]: x = np.array([1.48,1.41,0.0,0.1])

In [73]: using_indexed_assignment(x)
Out[73]: array([3, 2, 0, 1])

这检查它们都产生相同的结果:

x = np.random.random(10**5)
expected = using_indexed_assignment(x)
for func in (using_argsort_twice, using_digitize, using_rankdata):
    assert np.allclose(expected, func(x))

这些IPython %timeit基准测试建议大型数组using_indexed_assignment是最快的:

In [50]: x = np.random.random(10**5)
In [66]: %timeit using_indexed_assignment(x)
100 loops, best of 3: 9.32 ms per loop

In [70]: %timeit using_rankdata(x)
100 loops, best of 3: 10.6 ms per loop

In [56]: %timeit using_argsort_twice(x)
100 loops, best of 3: 16.2 ms per loop

In [59]: %timeit using_digitize(x)
10 loops, best of 3: 27 ms per loop

对于小型数组,using_argsort_twice可能更快:

In [78]: x = np.random.random(10**2)

In [81]: %timeit using_argsort_twice(x)
100000 loops, best of 3: 3.45 µs per loop

In [79]: %timeit using_indexed_assignment(x)
100000 loops, best of 3: 4.78 µs per loop

In [80]: %timeit using_rankdata(x)
100000 loops, best of 3: 19 µs per loop

In [82]: %timeit using_digitize(x)
10000 loops, best of 3: 26.2 µs per loop

另请注意,stats.rankdata可让您更好地控制如何处理相等价值的元素。

答案 2 :(得分:2)

正如the documentation所说,argsort

  

返回对数组进行排序的索引。

这意味着argsort的第一个元素是应该首先排序的元素的索引,第二个元素是应该是第二个元素的索引,等等。

您似乎想要的是值的排名顺序,这是scipy.stats.rankdata提供的顺序。请注意,如果队伍中存在关联,您需要考虑应该发生什么。

答案 3 :(得分:0)

首先,它订购了阵列。然后生成一个包含数组初始索引的数组。

答案 4 :(得分:0)

输入:
    导入numpy为np
    x = np.array([1.48,1.41,0.0,0.1])
    x.argsort()。argsort()

输出:
数组([3,2,0,1])

答案 5 :(得分:0)

np.argsort返回由“种类”(指定排序算法的类型)给出的排序数组的索引。但是,当列表与np.argmax一起使用时,它将返回列表中最大元素的索引。而np.sort对给定的数组,列表进行排序。

答案 6 :(得分:0)

numpy.argsort(a,axis = -1,kind ='quicksort',order = None)

返回将对数组进行排序的索引

使用kind关键字指定的算法沿给定的轴执行间接排序。它将沿给定轴按排序顺序返回与该索引数据形状相同的索引数组。

考虑python中的一个示例,其值列表为

listExample  = [0 , 2, 2456,  2000, 5000, 0, 1]

现在我们使用argsort函数:

import numpy as np
list(np.argsort(listExample))

输出将为

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

这是listExample中值索引的列表,如果将这些索引映射到各自的值,那么我们将得到如下结果:

[0, 0, 1, 2, 2000, 2456, 5000]

(我发现此功能在许多地方都非常有用,例如,如果您想对列表/数组进行排序,但又不想使用list.sort()函数(即,不更改列表中实际值的顺序),可以使用此功能。)

有关更多详细信息,请参见以下链接:https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.argsort.html

答案 7 :(得分:0)

它根据给定的数组索引返回索引,这意味着: 0.0是索引[2]中的第一个元素 0.1是索引[3]中的第二个元素 1.41是索引[1]中的第三个元素 1.48是索引[0]中的第四个元素 输出:

[2,3,1,0]

答案 8 :(得分:-1)

只是想直接将OP的原始理解与代码的实际实现进行对比。

numpy.argsort定义为1D数组:

x[x.argsort()] == numpy.sort(x) # this will be an array of True's

OP最初认为它是针对1D阵列定义的:

x == numpy.sort(x)[x.argsort()] # this will not be True

注意:此代码在一般情况下不起作用(仅适用于1D),此答案纯粹是为了说明目的。

相关问题