为什么python中不同计算机的强制转换规则不同?



我在我的Mac上运行python 2.7,我正在和其他使用Ubuntu的人一起做一个小组编码项目。每隔一段时间,他们写的代码不能在我的电脑上工作,因为强制转换规则错误:

    273     # Apply column averages to image
--> 274     img[:middle] *= (bg[0]/np.tile(topCol, (middle,1)))
    275     img[middle:] *= bg[1]/np.tile(botCol, (middle,1))
    276 
TypeError: Cannot cast ufunc multiply output from dtype('float64') to dtype('int16') with casting rule 'same_kind'

我认为你不需要详细说明,因为这种情况发生在不同的数字类型的几个不同的地方。

在他们所有的电脑上都可以用,没问题。我写的东西对他们都有用,但他们写的东西对我却常常不起作用。

我们的机器有什么不一致的原因吗?我有什么办法可以在我这边改变吗?

谢谢!

这个线程表明您的numpy比您的同事正在使用的版本更新(请检查使用numpy.version.version)。在1.7.0开发分支中,似乎他们已经将隐式强制转换规则更改为更严格的same_kind规则,该规则禁止(除其他事项外)在浮点数和整数格式之间进行强制转换。

为了解决这个问题,我建议使用这样的代码:
img[:middle] *= (bg[0]/np.tile(topCol, (middle,1))).astype(img.dtype)

nneonneo有一个正确的解决方案,我想我应该添加一些其他的工作。

一个问题是img变量早先被手动定义为int。那么带有float的乘法就违反了严格类型强制转换

img = np.int16( cp.deepcopy(imgArray) )
...
img[:middle] *= bg[0]/np.tile(topCol, (middle,1))
>>TypeError: Cannot cast ufunc multiply output from dtype('float64') to dtype('int16') with casting rule 'same_kind'

一种变通方法:

我可以更改初始变量类型定义以匹配后面需要的内容:

img = np.float64( cp.deepcopy(imgArray) )
...
img[:middle] *= bg[0]/np.tile(topCol, (middle,1))

或者我可以保持原来的类型强制转换,并更改操作符:

img = np.int16( cp.deepcopy(imgArray) )
...
img[:middle] = img[:middle]*bg[0]/np.tile(topCol, (middle,1))

由于某些原因,Numpy允许这样操作,而*=

则不允许。

谢谢你的帮助!

引用numpy开发人员的话(http://docs.scipy.org/doc/numpy-dev/release.html):

本地操作的默认强制类型转换已更改为'same_kind'。例如,如果n是一个整数数组,而f是一个浮点数数组,那么n += f将导致TypeError,而在以前的Numpy版本中,浮点数将被静默地强制转换为int。在不太可能的情况下,示例代码不是实际的错误,可以通过将其重写为np以向后兼容的方式更新它。添加(n, f, out=n, casting='不安全')。旧的"不安全"默认值自Numpy 1.7起已弃用。

因此,如果您想保留原地乘法,代码将变为:

np.multiply(img[:middle], (bg[0]/np.tile(topCol, (middle,1))), out=img[:middle], casting='unsafe')

相关内容

  • 没有找到相关文章

最新更新