numpy或python中的等效matlab函数mod

Kha*_*oti 4 python floating-point matlab numpy

我正在将一些代码从Matlab转换为Python。

在matlab中,有mod给出模运算的函数。

例如,以下示例显示了matlab mod和等效的numpy remainder操作之间的不同结果:

Matlab:

>> mod(6, 0.05)

ans =

     0
Run Code Online (Sandbox Code Playgroud)

脾气暴躁:

np.remainder(6, 0.05) 
0.04999999999999967

np.mod(6, 0.05)
0.04999999999999967
Run Code Online (Sandbox Code Playgroud)

Python模运算符给出的结果与numpy相同。

6%0.05
0.04999999999999967
Run Code Online (Sandbox Code Playgroud)

python中有什么可以提供与Matlab中相同的mod操作吗?最好可以在numpy2d / 3d阵列上进行操作。

numpy 文档说,这numpy.mod等效于matlab mod

And*_*eak 6

这是问题的核心,在python中:

>>> 6/0.05 == 120
True

>>> 6//0.05 == 120  # this is 119 instead
False
Run Code Online (Sandbox Code Playgroud)

的浮点结果6/0.05足够接近120(即在双精度的分辨率内),因此将其舍入为120.0。但是,它比120小得多,因此显式的楼层分割会将该数字截断为119,然后再将其归一化为120.0。

一些证明:

>>> from decimal import Decimal
... print(6/Decimal(0.05))  # exactly approximate
... print(6/Decimal('0.05'))  # exact
119.9999999999999933386618522
1.2E+2
Run Code Online (Sandbox Code Playgroud)

第一个数字是您首先得到的6/0.05,但是该数字119.9999999999999933386618522将四舍五入到可以用双精度表示的最接近的数字,即120。可以很容易地证明这两个数字在双精度内确实相同:

>>> print(6/Decimal('0.05') - 6/Decimal(0.05))
6.6613381478E-15

>>> 120 - 6.6613381478E-15 == 120
True
Run Code Online (Sandbox Code Playgroud)

现在help mod来自MATLAB:

>>> from decimal import Decimal
... print(6/Decimal(0.05))  # exactly approximate
... print(6/Decimal('0.05'))  # exact
119.9999999999999933386618522
1.2E+2
Run Code Online (Sandbox Code Playgroud)

这表明当x/y接近整数时,将其四舍五入,而不是像在python中那样被截断。因此,MATLAB竭尽全力对浮点结果进行了一些处理。

最简单的解决方案是自己对数字取整(除非可以使用decimal.Decimal,否则这意味着您应该完全放弃本机双精度,包括文字)并以mod这种方式重现MATLAB的假设,前提是这对您的用例有意义。