17

我在我的 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'

我认为您不需要详细信息,因为这发生在具有不同数字类型的几个不同地方。

它适用于他们所有的计算机没问题。我写的所有东西都对他们有用,但他们写的东西经常对我不起作用。

我们的机器不同意有什么原因吗?有什么方法可以改变我的结果吗?

谢谢!

4

3 回答 3

16

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

要解决此问题,我建议使用如下代码:

img[:middle] *= (bg[0]/np.tile(topCol, (middle,1))).astype(img.dtype)
于 2013-01-11T01:26:24.027 回答
5

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 允许以这种方式进行操作,而它不会*=

感谢所有的帮助!

于 2013-01-11T20:20:22.670 回答
2

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

就地操作的默认转换已更改为“same_kind”。例如,如果 n 是一个整数数组,而 f 是一个浮点数数组,那么 n += f 将导致 TypeError,而在以前的 Numpy 版本中,浮点数会被默默地转换为整数。在示例代码不是实际错误的不太可能的情况下,可以通过将其重写为 np.add(n, f, out=n, cast='unsafe') 以向后兼容的方式对其进行更新。自 Numpy 1.7 以来,旧的“不安全”默认值已被弃用。

因此,如果你想保持原地乘法,代码变成:

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

于 2016-04-03T13:43:04.043 回答