numpy.searchsorted为包含numpy.nan的数组

时间:2014-12-02 17:54:50

标签: python arrays numpy nan

我想:

index = numpy.searchsorted(array([  1.,   2.,   3.,  nan,   4.,   5.]), 4.2, side='left')

给我:

index = 4

这最多可达3.9,但不能在数组中的nan之后。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

您要排序的数组未排序,需要searchsorted才能正常工作。 np.nan将出现在排序数组的最后:

>>> np.sort([1., 2., 3., nan, 4., 5.])
array([  1.,   2.,   3.,   4.,   5.,  nan])

要解决此问题,您可以使用sorter关键字参数传入数组的已排序索引列表。您可以使用np.argsort来查找:

>>> arg_sorted = np.argsort([1., 2., 3., nan, 4., 5.])
>>> np.searchsorted([1., 2., 3., nan, 4., 5.], 4.2, side='right', sorter=arg_sorted)
4                     

编辑:根据下面Jaime的评论,传递sorter参数意味着该函数返回排序数组中的位置(而不是未排序的数组)。由于side='left'指定应返回第一个合适的索引,因此可以使用np.searchsorted使用以下方法更好地识别正确的索引:

>>> idx = np.searchsorted([1., 2., 3., nan, 4., 5.], 4.2, side='left')
>>> arg_sorted[idx]
4

答案 1 :(得分:0)

我没有足够的声誉来添加评论,所以我会在答案中加上我的两分钱。

我遇到过类似的挑战,据我所知,answer可能存在问题。

为了说明我的观点,我用一个额外的元素

扩展了有问题的数组
a = np.array([1., 2., 3., np.nan, 4., 5., 6.])

并像以前一样调用argsort算法

arg_sorted = np.argsort(a)

此外,除了发现4.2之外,我还考虑5.2。然后,建议的解决方案的输出是

for x in [4.2, 5.2]:
    ind_tmp = np.searchsorted(a, x, side='left')
    ind = arg_sorted[ind_tmp]
    print('x={}, ind={}'.format(x, ind))

x=4.2, ind=4
x=5.2, ind=4

我相信使用sorter参数找到更正确的答案,就像这样

for x in [4.2, 5.2]:
    ind_tmp = np.searchsorted(a, x, side='left', sorter=arg_sorted)
    ind = arg_sorted[ind_tmp]
    print('x={}, ind={}'.format(x, ind))

x=4.2, ind=5
x=5.2, ind=6

在这种情况下,5.2高于4.2的索引,与原始答案相反,更符合我对正确解决方案的理解。