Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 查找numpy数组的k个最小值的索引_Python_Numpy - Fatal编程技术网

Python 查找numpy数组的k个最小值的索引

Python 查找numpy数组的k个最小值的索引,python,numpy,Python,Numpy,为了找到最小值的索引,我可以使用argmin: import numpy as np A = np.array([1, 7, 9, 2, 0.1, 17, 17, 1.5]) print A.argmin() # 4 because A[4] = 0.1 但是我怎样才能找到k-最小值的指数呢 我要找的东西是: print A.argmin(numberofvalues=3) # [4, 0, 7] because A[4] <= A[0] <= A[7] <

为了找到最小值的索引,我可以使用
argmin

import numpy as np
A = np.array([1, 7, 9, 2, 0.1, 17, 17, 1.5])
print A.argmin()     # 4 because A[4] = 0.1

但是我怎样才能找到k-最小值的指数呢

我要找的东西是:

print A.argmin(numberofvalues=3)   
# [4, 0, 7]  because A[4] <= A[0] <= A[7] <= all other A[i]
打印A.argmin(numberofvalues=3)
#[4,0,7]因为[4]可以用于切片

>>> import numpy as np
>>> A = np.array([1, 7, 9, 2, 0.1, 17, 17, 1.5])
>>> np.argsort(A)[:3]
array([4, 0, 7], dtype=int32)
使用。它不会对整个数组进行排序。它只保证
kth
元素处于排序位置,并且所有较小的元素都将在它之前移动。因此,第一个
k
元素将是k个最小元素

import numpy as np

A = np.array([1, 7, 9, 2, 0.1, 17, 17, 1.5])
k = 3

idx = np.argpartition(A, k)
print(idx)
# [4 0 7 3 1 2 6 5]
这将返回k-最小值。请注意,这些可能不是按顺序排序的

print(A[idx[:k]])
# [ 0.1  1.   1.5]

要获得k最大值,请使用

idx = np.argpartition(A, -k)
# [4 0 7 3 1 2 6 5]

A[idx[-k:]]
# [  9.  17.  17.]
警告:不要(重新)使用
idx=np.argpartition(A,k);A[idx[-k:]
以获取k最大值。 这并不总是有效的。例如,这些不是
x
中的3个最大值:

x = np.array([100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0])
idx = np.argpartition(x, 3)
x[idx[-3:]]
array([ 70,  80, 100])

这里是与
np.argsort
的比较,它也可以工作,但只是对整个数组进行排序以获得结果

In [2]: x = np.random.randn(100000)

In [3]: %timeit idx0 = np.argsort(x)[:100]
100 loops, best of 3: 8.26 ms per loop

In [4]: %timeit idx1 = np.argpartition(x, 100)[:100]
1000 loops, best of 3: 721 µs per loop

In [5]: np.alltrue(np.sort(np.argsort(x)[:100]) == np.sort(np.argpartition(x, 100)[:100]))
Out[5]: True

numpy.partition(您的_数组,k)
是另一种选择。无需切片,因为它将给出排序后的值,直到
kth
元素。

对于n维数组,此函数运行良好。索引以可调用的形式返回。如果希望返回索引列表,则需要在创建列表之前转置数组

要检索最大的
k
,只需传入
-k

def get_indices_of_k_smallest(arr, k):
    idx = np.argpartition(arr.ravel(), k)
    return tuple(np.array(np.unravel_index(idx, arr.shape))[:, range(min(k, 0), max(k, 0))])
    # if you want it in a list of indices . . . 
    # return np.array(np.unravel_index(idx, arr.shape))[:, range(k)].transpose().tolist()
例如:

r = np.random.RandomState(1234)
arr = r.randint(1, 1000, 2 * 4 * 6).reshape(2, 4, 6)

indices = get_indices_of_k_smallest(arr, 4)
indices
# (array([1, 0, 0, 1], dtype=int64),
#  array([3, 2, 0, 1], dtype=int64),
#  array([3, 0, 3, 3], dtype=int64))

arr[indices]
# array([ 4, 31, 54, 77])

%%timeit
get_indices_of_k_smallest(arr, 4)
# 17.1 µs ± 651 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

谢谢但是计算所有的
argsort
然后只保留k不是很慢吗(如果不知道
argsort
的实现,很难说。具体地说,如果它是作为生成器实现的,并且取决于实际的排序算法,它可能是懒惰的,或者它可能会首先对整个集合进行排序,我不确定。从其他注释来看,似乎
argsort
对整个集合进行排序,因此我将参考使用
argpartition
的其他建议解决方案之一此解决方案的优点(与
argpartition
相比)是,我们可以保证我们要查找的k个索引是按升序排列的。请参阅,尤其是第二个答案,以获取此问题的最佳解决方案(它是O(n))-对整个数组进行完全排序并非绝对必要)。类似:这会将索引
k
(可能未排序)处的元素置于排序位置。由于排序位置不是索引
k
k-1
所必需的,因此我们无法保证
您的_数组[:k]
包含
k
numpy.partition
之后的最小元素。这是2019年10月数组值(不是索引)的最佳答案。@Progator我不理解您的评论。如果有错误,请纠正我,但证明此分区函数正确工作的证据是在循环中运行以下内容:y=np.arange(10) ;np.random.shuffle(y);y.partition(3);断言y[:3+1].max()…分区函数在旧的numpy版本或其他版本中是否有不同的行为?仅供参考:
k
是零索引的。你知道这是如何处理关系的吗?如果你想随机中断关系,唯一可能的方法是使用lexsort对整个数组进行排序。分区文档说introselect不稳定,但我不确定是否不稳定他的意思是随机断开关系。@user27182:Per,如果
a
是一个带有字段的数组(即a),那么您可以指定
顺序,或者让未指定的字段用于断开关系。因此,如果您将
a
倒入结构化数组的第一个字段,则将其倒入随机(断开关系)将数字输入第二个字段,然后使用
np.argpartition
选择
k
最小(或最大)随机平局。请记住,第一个
k-1
元素不能保证从最小到最大的顺序。如果需要,可以使用
np.argpartition
,使用第一个
k
索引对数组进行切片,然后对生成的数组使用
np.argsort