在ndarray找到浮动

2024-10-06 12:20:07 发布

您现在位置:Python中文网/ 问答频道 /正文

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

示例代码:

import numpy as np

array = np.arange(10)
number = 5.00001

如果我这样做:

^{pr2}$

结果为空,因为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公司()正是我正在寻找的函数,我错过了它,因为它不在文档中。。。如果不是你们,直到他们更新了医生我才意识到这一点。再次感谢你!在


Tags: 方法代码importnumpy示例numberasnp
3条回答

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...

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

>>> a = np.array([[2.000000000001, 2.0000000002], [2.000000000001, 1.999999999]])
>>> np.allclose(a, 2)
True

作为旁注,如果您真的需要一个包含所有2的数组,有一种比2乘以ones更简单的方法:

^{pr2}$

对于这个问题,我不知道你为什么要做[array.shape[0], array.shape[1]]。如果数组是2D,则与array.shape完全相同。如果数组可能更大,它与array.shape[:2]完全相同。在


我更想知道他们是否真的解决了问题。但事实上,你说你可以使用allclose,如果不是因为它太冗长而无法创建可比较的数组。在

所以,如果你需要whereclose而不是allclose那么,没有这样的函数。但是建立你自己是很容易的,如果你反复做的话,你总是可以结束它。在

如果您有一个isclose方法,比如allclose,但是返回一个bool数组而不是一个bool,那么您可以写:

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

……或者,如果你一遍又一遍地做:

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 does have exactly that function(另请参见here)的1.7版本,但文档中似乎没有。如果您不想依赖一个可能没有文档的函数,或者不需要使用numpy 1.6,您可以自己编写它:

def isclose(a, b, rtol=1e-05, atol=1e-08):
    return np.abs(a-b) <= (atol + rtol * np.abs(b))

如果您有最新的numpy(1.7),那么最好的方法是使用^{},它将自动广播这些形状:

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

或者,如果您只期望一个匹配:

^{pr2}$

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

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

下面是另一种可能有用的方法。我不确定它是否适用于您的情况,但是如果您在数组中查找多个数字(这是一个常见的用例),这可能会非常有用。它的灵感来源于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)]

相关问题 更多 >