python - 使用浮点 NumPy 数组进行比较和相关操作

标签 python arrays numpy random precision

我有一组随机 float ,我需要将它与另一个具有相同值但顺序不同的数组进行比较。就此而言,我使用总和、乘积(以及其他组合,具体取决于表格的尺寸,因此需要方程的数量)。

然而,当我根据值的顺序对数组执行求和(或乘积)时遇到了精度问题。

这是一个简单的独立示例来说明这个问题:

import numpy as np

n = 10
m = 4

tag = np.random.rand(n, m)

s1 = np.sum(tag, axis=1)
s2 = np.sum(tag[:, ::-1], axis=1)

# print the number of times s1 is not equal to s2 (should be 0)
print np.nonzero(s1 != s2)[0].shape[0]

如果您执行此代码,它有时会告诉您 s1s2 不相等,并且计算机精度的差异很大。

问题是我需要在像 np.in1d 这样的函数中使用那些我不能真正给出容差的地方......

有没有办法避免这个问题?

最佳答案

对于列出的代码,您可以使用np.isclose也可以指定公差值。

使用提供的示例,让我们看看如何使用它 -

In [201]: n = 10
     ...: m = 4
     ...: 
     ...: tag = np.random.rand(n, m)
     ...: 
     ...: s1 = np.sum(tag, axis=1)
     ...: s2 = np.sum(tag[:, ::-1], axis=1)
     ...: 

In [202]: np.nonzero(s1 != s2)[0].shape[0]
Out[202]: 4

In [203]: (~np.isclose(s1,s2)).sum() # So, all matches!
Out[203]: 0

要在其他场景中使用公差值,我们需要根据具体情况进行工作。因此,假设对于像 np.in1d 中那样涉及元素比较的实现,我们可以引入 broadcasting。针对第二个输入中的所有元素对第一个输入中的所有元素进行元素相等性检查。然后,我们使用 np.abs 获取“接近因子”,最后与输入容差进行比较以确定匹配项。根据模拟 np.in1d 的需要,我们沿着其中一个轴进行任何操作。因此,可以像这样实现使用 broadcasting 的容差 np.in1d -

def in1d_with_tolerance(A,B,tol=1e-05):
    return (np.abs(A[:,None] - B) < tol).any(1)

正如 OP 的评论中所建议的,我们还可以在按比例放大后舍入 float 字,这应该是内存高效的,因为需要处理大型数组。所以,修改后的版本应该是这样的——

def in1d_with_tolerance_v2(A,B,tol=1e-05):
    S = round(1/tol)
    return np.in1d(np.around(A*S).astype(int),np.around(B*S).astype(int))

sample 运行-

In [372]: A = np.random.rand(5)
     ...: B = np.random.rand(7)
     ...: B[3] = A[1] + 0.0000008
     ...: B[6] = A[4] - 0.0000007
     ...: 

In [373]: np.in1d(A,B) # Not the result we want!
Out[373]: array([False, False, False, False, False], dtype=bool)

In [374]: in1d_with_tolerance(A,B)
Out[374]: array([False,  True, False, False,  True], dtype=bool)

In [375]: in1d_with_tolerance_v2(A,B)
Out[375]: array([False,  True, False, False,  True], dtype=bool)

最后,关于如何使其适用于其他实现和用例 - 这将取决于实现本身。但对于大多数情况,np.isclosebroadcasting 应该会有所帮助。

关于python - 使用浮点 NumPy 数组进行比较和相关操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39757559/

相关文章:

php - array_walk() 是做什么的?

python - JSONSchema 暗示其架构的资源

python - Astropy ICRS 到银河中心变换 Numpy AttributeError

python - Google Calendar API 仅获取日历的第一个事件

javascript - for 循环的替代方案

python - numpy 直方图 bool 索引与沿维度 0 的索引数组不匹配;维度是

python - 将 int 转换为字符串以添加到 map python 的函数

c++ - 我是否正确使用指针和数组?

python - numpy.histogram() 是如何工作的?

python - 接受值网格的函数