对于这段代码,您可以使用
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()
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在评论中建议的那样,我们可以在将浮点数放大后四舍五入,这样可以节省内存,特别适用于处理大型数组。因此,修改后的版本应该像这样 -
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))
样例运行:
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)
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.isclose
和broadcasting
应该有所帮助。
statistics
模块中有一些更高级的求和方法,但现在这不是重点。特别是在numpy中,向量化应该是一种基本工具,你永远不能依赖算术运算的顺序。 - Andras Deak -- Слава Україніnp.in1d
?对于所列代码,你可以使用np.isclose(s1,s2)
。 - Divakarnp.in1d(s1, s2)
和其他通过其他操作(如乘积等)获得的等效数组... - Thomas Leonard