[英]Equivalent matlab function mod in numpy or python
我正在将一些代码从Matlab转换为Python。
在matlab中有函数mod
,它给出了模运算。
例如,以下示例显示了matlab mod
和等效numpy remainder
操作之间的不同结果:
Matlab的:
>> mod(6, 0.05)
ans =
0
NumPy的:
np.remainder(6, 0.05)
0.04999999999999967
np.mod(6, 0.05)
0.04999999999999967
Python模运算符给出与numpy相同的结果。
6%0.05
0.04999999999999967
python中有没有提供与Matlab相同的mod操作? 优选地,可以在numpy
2d / 3d阵列上操作。
numpy
文档说numpy.mod
相当于matlab mod
。
这是问题的核心,在python中:
>>> 6/0.05 == 120
True
>>> 6//0.05 == 120 # this is 119 instead
False
6/0.05
的浮点结果足够接近120(即在双精度的分辨率内),它被舍入到120.0。 但是,它比120略小,因此明确的分区将在将其标准化为120.0之前将该数字截断为119。
一些证据:
>>> from decimal import Decimal
... print(6/Decimal(0.05)) # exactly approximate
... print(6/Decimal('0.05')) # exact
119.9999999999999933386618522
1.2E+2
第一个数字是你最初得到的6/0.05
,但数字119.9999999999999933386618522
四舍五入到最接近的数字,用双精度表示,这是120.可以很容易地证明这两个数字在双精度内确实是相同的:
>>> print(6/Decimal('0.05') - 6/Decimal(0.05))
6.6613381478E-15
>>> 120 - 6.6613381478E-15 == 120
True
现在来自MATLAB的help mod
:
MOD(x,y) returns x - floor(x./y).*y if y ~= 0, carefully computed to
avoid rounding error. If y is not an integer and the quotient x./y is
within roundoff error of an integer, then n is that integer.
这表明当x/y
接近整数时,它首先舍入,而不是像python中那样被截断。 所以MATLAB不遗余力地利用浮点结果做一些魔术。
最简单的解决方案是自己舍入你的数字(除非你可以使用像decimal.Decimal
这样的decimal.Decimal
,但这意味着你应该完全放弃原生双打,包括文字)并以这种方式重现MATLAB的mod
,假设对你的用例有意义。
这是一个解决方法。 它基本上将分母舍入到它的str表示,并从那里进行整数运算:
import numpy as np
import decimal
def round_divmod(b,a):
n,d = np.frompyfunc(lambda x:decimal.Decimal(x).as_integer_ratio(),1,2)(a.astype('U'))
n,d = n.astype(int),d.astype(int)
q,r = np.divmod(b*d,n)
return q,r/d
a = np.round(np.linspace(0.05,1,20),2).reshape(4,5)
a
# array([[0.05, 0.1 , 0.15, 0.2 , 0.25],
# [0.3 , 0.35, 0.4 , 0.45, 0.5 ],
# [0.55, 0.6 , 0.65, 0.7 , 0.75],
# [0.8 , 0.85, 0.9 , 0.95, 1. ]])
round_divmod(6,a)
# (array([[120, 60, 40, 30, 24],
# [ 20, 17, 15, 13, 12],
# [ 10, 10, 9, 8, 8],
# [ 7, 7, 6, 6, 6]]), array([[0. , 0. , 0. , 0. , 0. ],
# [0. , 0.05, 0. , 0.15, 0. ],
# [0.5 , 0. , 0.15, 0.4 , 0. ],
# [0.4 , 0.05, 0.6 , 0.3 , 0. ]]))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.