从numpy数组中获取最小的N个值,忽略inf和nan。

7
我需要一个好的、快速的方法来找出numpy数组中任意多个nan和/或inf值的10个最小实值。
我需要确定这些最小实值的索引,而不是它们本身的值。
我已经发现了numpy中的argmin和nanargmin函数。但由于我想指定多个值,例如我想要最小的100个值,所以它们并没有完成任务。此外,它们返回的最小值包括-无穷大,而当其存在于数组中时,它并不是真正的最小值。
heapq.nsmallest有点可行,但它也将nan和-inf值作为最小值返回。此外,它并没有给我需要的索引。
非常感谢您的帮助。

迭代/复制数组,将所有的NaN和-inf转换为inf,运行您的函数以获取最小的N个值,然后将它们转换回旧副本。这是一个愚蠢的hacky方法,但是嗯... - Patashu
谢谢您的帮助,如果我无法得到更简单的答案,那就是我必须要做的。 - jeffery_the_wind
3个回答

11

应该排除的唯一值是负无穷大。因此,请尝试:

import numpy as np
a = np.random.rand(20)
a[4] = -np.inf
k = 10
a[np.isneginf(a)] = inf
result = a[np.argsort(a)[:k]]

1
如果所有元素都是负数,2*np.max 就无法正常工作,我认为最好使用 inf - interjay
1
当前的解决方案可能是危险的。在这里应该注意,您正在更改数组以进行测量。物理上的意义可能是-inf不等于inf - Hooked
2
如果你愿意的话,可以避免修改原始数组。只需无条件排序,然后将结果限制在有限值范围内:i = np.argsort(a); result = i[np.isfinite(a[i])][:10] - Blckknght
@Blckknght 是的,那是一个更好的解决方案。如果你发布了那个,我会删除我的回答。 - YXD

2

在我看来,你可以只从已排序的数组中取前 n 个有限值,而不是尝试修改原始数组,这可能会有危险。

n = 10
b = np.sort(a)
smalls = b[np.isfinite(b)][n:]

1
您可以像这样查找infNan的索引:
a=np.array([[12,12,111],[np.inf,np.inf,1,2,3],[np.nan,7,8]])

你可以循环遍历 a 并使用以下代码进行检查:
for item in a:    
    idxInf=(np.isnan(a[item])).nonzero()
    idxNan=(np.isnan(a[item])).nonzero()

i.e:

In [17]: (np.isnan(a[2]))
Out[17]: array([ True, False, False], dtype=bool)

In [18]: (np.isnan(a[2])).nonzero()
Out[18]: (array([0]),)

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