【发布时间】:2013-09-29 17:32:03
【问题描述】:
简化问题
我可以让 Numpy 同意 Matlab 和 Python 的 round 吗?
Matlab 2013a:
>> round(-0.5)
ans =
-1
Python(使用 Numpy 数组,或者只是一个标量,结果相同):
>>> import numpy
>>> round(numpy.array(-0.5))
-1.0
Numpy,奇怪的是:
>>> import numpy
>>> numpy.round(numpy.array(-0.5))
-0
这种差异是否取决于圆形平台?
原问题
Matlab 附带一个文件“handel.mat”,其中包含一些音频数据:
>> which handel.mat
C:\Program Files\MATLAB\R2013a\toolbox\matlab\audiovideo\handel.mat
>> load handel
>> soundsc(y) % play the short audio clip
我想在 Python 中处理这些数据,所以我使用 scipy.io.loadmat [1]。具体来说,我想缩放音频的值以跨越 16 位有符号整数的整个范围,即音频信号的最小值映射到 -2^15,最大的值映射到 2^15-1。在 Matlab 中执行此操作时,我感到很惊讶,结果与 Python 不同:
Matlab:
>> load handel
>> int16(round(interp1([min(y), max(y)], [-2^15, 2^15-1], y(1:10))))
ans =
-1 %%% <-- Different from Python
-253
-3074
-1277
252
1560
772
-1025
-1277
-3074
Python:
In [1]: import numpy as np
In [2]: import scipy.io as io
In [3]: mat = io.loadmat('handel.mat')
In [4]: np.int16(np.round(np.interp(mat['y'][:10], [mat['y'].min(), mat['y'].max()], [-2.0**15, 2.0**15-1.0])))
Out[4]:
array([[ 0], ### <-- Different from Matlab
[ -253],
[-3074],
[-1277],
[ 252],
[ 1560],
[ 772],
[-1025],
[-1277],
[-3074]], dtype=int16)
实际上有 1231 个样本(总共 73113 个)Python 和 Matlab 不同。我想我对我的类型很小心,但实际上,类型错误在这里蔓延的错误表面很少:loadmat 应该从 MAT 文件中推断类型,而 int16 在两者之间不会有太大差异系统。
添加interp/interp1d 命令输出的第一个元素都是 -0.5(在 Python 和 Matlab 中都将其打印到小数点后 100 位证实了这一点),但四舍五入在 Numpy (np.round) 中产生 0,而 Matlab 将其四舍五入为 -1。这是 Matlab 舍入语义的问题吗? Furthermore Python 内置的非 Numpy round for -0.5 给了我 -1! Numpy 和 Python 的 round 函数之间的差异从何而来? Python 的 round 是否总是匹配 Matlab 的?
Windows64、Matlab 8.1 (2013a)、Python 2.7.4。
[1]http://docs.scipy.org/doc/scipy/reference/generated/scipy.io.loadmat.html
【问题讨论】:
-
如果您不将值缩放到 int16,两种情况下的读数是否相同?如果是的话,我会进一步检查
np.linspace()后者函数的行为;圆形,interp 和 int16。我猜这可能是圆形或插值函数的行为略有不同? -
@Faultier 在底部检查我的编辑,看起来区别在于
round的输出(Matlab vs Numpy vs Python)。有什么建议吗? -
我认为这是定义的主题 - 你想要什么行为?我只会使用相应的圆形功能。另外,请参阅有关此主题的 numpy 手册草案:docs.scipy.org/doc/numpy/reference/generated/…
-
我的 0.02 美元:起初可能令人惊讶的是,有多个定义如何舍入恰好介于两个整数之间的值。 The Wikipedia site on rounding has a good explanation on what is called tie-breaking.
标签: python matlab numpy rounding numerical