Find float in ndarray
我试图在Ndarray中找到一个浮点数。由于我使用的软件包(ABAQUS),它的输出精度有点低。例如,10类似于10.00003。因此,我想知道是否有一种"正确"的方法来做到这一点,这比我的代码整洁。
示例代码:
1 2 3 4 | import numpy as np array = np.arange(10) number = 5.00001 |
如果我这样做:
1 | idx = np.where(number==array)[0][0] |
号
则结果为空,因为5.00001不等于5。
现在我在做:
1 2 | atol = 1e-3 # Absolute tolerance idx = np.where(abs(number-array) < atol)[0][0] |
这很有效,而且不太乱…但我想有一个更整洁的方法来做这件事。谢谢!
附言:
编辑:非常感谢大家的精彩回答!isclose()是我正在寻找的确切函数,我错过了它,因为它不在文档中…如果不是你们,在他们更新医生之前我不会意识到这一点。再次感谢!
PS: numpy.allclose() is another way to do it, but I need to use number * np.ones([array.shape[0], array.shape[1]]) and it still seems verbose to me...
号
你几乎不需要做像
1 2 3 | >>> a = np.array([[2.000000000001, 2.0000000002], [2.000000000001, 1.999999999]]) >>> np.allclose(a, 2) True |
作为补充说明,如果您确实需要一个包含所有2的数组,那么有一种比将2乘以
1 2 | >>> np.tile(2, array.shape) array([[2, 2], [2, 2]]) |
号
关于这件事,我不知道你为什么要这么做。如果数组是二维的,这与
我不确定这是否能解决你的实际问题,因为你似乎想知道哪些是接近的,哪些不是接近的,而不仅仅是它们是否都是。但事实上,如果不是因为创建数组过于冗长而无法与之相比,您说过可以使用
所以,如果你需要
如果您有一个类似于
1 | idx = np.where(isclose(a, b, 0, atol))[0][0] |
…或者,如果你一次又一次地这样做:
1 2 3 4 | 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] |
。
事实证明,numpy的1.7版确实有这个功能(请参见此处),但它似乎不在文档中。如果您不想依赖一个可能没有文档的函数,或者需要使用numpy 1.6,那么您可以自己编写它:
1 2 | def isclose(a, b, rtol=1e-05, atol=1e-08): return np.abs(a-b) <= (atol + rtol * np.abs(b)) |
如果您有最新的numpy(1.7),那么最好的方法是使用
1 2 3 4 5 | import numpy as np a = np.arange(10) n = 5.000001 np.isclose(a, n).nonzero() #(array([5]),) |
。
或者,如果您只期望一个匹配:
1 2 | np.isclose(a, n).nonzero()[0][0] #5 |
。
(
上面使用的方法,特别是
下面是另一种可能有用的方法。我不确定它是否适用于您的案例,但是如果您在数组中查找多个数字(这是一个常见的用例),它可能会非常有用。它的灵感来自这个类似的问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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)] |