在ndarray中找到float

时间:2013-09-09 19:15:40

标签: python numpy precision

我试图在ndarray中找到一个浮点数。由于我使用的软件包(Abaqus),它输出的精度有点低。例如,10就像是10.00003。因此,我想知道是否有一种“正确”的方法,这比我的代码更整洁。

示例代码:

import numpy as np

array = np.arange(10)
number = 5.00001

如果我这样做:

idx = np.where(number==array)[0][0]

然后结果为空,因为5.00001不等于5.

现在我在做:

atol = 1e-3 # Absolute tolerance
idx = np.where(abs(number-array) < atol)[0][0]

哪个有效,而且不太乱......但我想知道会有一个更简洁的方法来做到这一点。谢谢!

PS:numpy.allclose()是另一种方法,但我需要使用number * np.ones([array.shape[0], array.shape[1]]),而且对我来说似乎仍然很冗长......


编辑:非常感谢你们的精彩答案! np.isclose()是我正在寻找的确切函数,我错过了,因为它不在文档中...我不会意识到这一点,直到他们更新文档,如果不是你们。再次感谢你!

3 个答案:

答案 0 :(得分:4)

  

PS:numpy.allclose()是另一种方法,但我需要使用数字* np.ones([array.shape [0],array.shape [1]]),它仍然看起来很冗长我...

你几乎不需要做number * np.ones([array.shape[0], array.shape[1]])之类的事情。正如您可以将该number数组的标量ones乘以1所有number值,您可以将该标量number传递给{ {1}}将所有原始数组的值与allclose进行比较。例如:

number

作为旁注,如果你真的需要一个包含所有2的数组,那么比用>>> a = np.array([[2.000000000001, 2.0000000002], [2.000000000001, 1.999999999]]) >>> np.allclose(a, 2) True 乘以2更简单的方法:

ones

就此而言,我不知道为什么你需要做>>> np.tile(2, array.shape) array([[2, 2], [2, 2]]) 。如果数组是2D,则与[array.shape[0], array.shape[1]]完全相同。如果数组可能更大,则与array.shape完全相同。


我不确定这会解决您的实际问题,因为您似乎想知道哪些哪些接近而不是接近,而不仅仅是它们是否都是。但是你说你可以使用array.shape[:2]的事实,如果不是因为创建要与之比较的数组过于冗长这一事实。

所以,如果你需要allclose而不是whereclose ......那么,就没有这样的功能了。但是自己构建起来非常容易,如果你反复这样做,你总是可以把它包起来。

如果你有类似allclose方法的isclose,但是返回一个bool数组而不是一个bool - 你可以写一下:

allclose

......或者,如果你一遍又一遍地这样做:

idx = np.where(isclose(a, b, 0, atol))[0][0]

事实证明,numpy does have exactly that function的版本1.7(另请参阅here),但它似乎不在文档中。如果您不想依赖可能未记录的函数,或者需要使用numpy 1.6,那么您可以自己轻松地编写它:

def whereclose(a, b, rtol=1e-05, atol=1e-08):
    return np.where(isclose(a, b, rtol, atol))

idx = whereclose(a, b, 0, atol)[0][0]

答案 1 :(得分:2)

如果您有最新的numpy(1.7),那么最好的方法是使用np.isclose自动将形状广播在一起:

import numpy as np
a = np.arange(10)
n = 5.000001
np.isclose(a, n).nonzero()
#(array([5]),)

或者,如果您只期望一场比赛:

np.isclose(a, n).nonzero()[0][0]
#5

np.nonzeronp.where基本相同,只是它没有if条件然后/ else功能)

答案 2 :(得分:0)

上面使用的方法,特别是abs(A - B) < atol,是跨多种语言进行浮点比较的标准。显然,使用numpy A和/或B可以是数组或数字。

这是另一种可能有用的方法。我不确定它适用于你的情况,但如果你在数组中寻找多个数字(这是一个常见的用例),它可能会非常有用。它的灵感来自this question,它有点类似。

import numpy as np

def find_close(a, b, rtol=1e-05, atol=1e-08):
    tol = atol + abs(b) * rtol
    lo = b - tol
    hi = b + tol
    order = a.argsort()
    a_sorted = a[order]
    left = a_sorted.searchsorted(lo)
    right = a_sorted.searchsorted(hi, 'right')
    return [order[L:R] for L, R in zip(left, right)]

a = np.array([2., 3., 3., 4., 0., 1.])
b = np.array([1.01, 3.01, 100.01])
print find_close(a, b, atol=.1)
# [array([5]), array([1, 2]), array([], dtype=int64)]