Numpy数组错误或功能(在幕后转换为int)?

时间:2014-11-18 21:18:54

标签: python arrays numpy

今天我注意到了Numpy / Scipy数组的奇怪行为。看起来像在float中添加带整数的数组单元格可能有两种不同的结果,具体取决于分配结果的变量。下面我将介绍代码:

,而不是长篇解释
import scipy as sp
array_int = sp.array([[0], [0]])
float_operand = 0.1
print array_int[0, 0] + float_operand #gives 0.1

但是

import scipy as sp
array_int = sp.array([[0], [0]])
float_operand = 0.1
array_int[0, 0] = array_int[0, 0] + float_operand 
print array_int[0, 0] #gives 0

我能理解这种行为是否继承自Python,但是:

与'#34;裸露"的行为相反Python(2.7):

integer_for_sure = int(0) 
integer_for_sure = integer_for_sure + 0.1
print integer_for_sure #gives 0.1 as expected

这种功能是否记录在案?有没有人以前遇到过它?

2 个答案:

答案 0 :(得分:3)

这不是“继承自Python”的行为 - 正如您所看到的,在纯Python中向int添加float会产生float结果。相反,您可以将此行为视为“继承自C”。与Python列表不同, numpy arrays具有强大的元素类型。数组构造函数包含一个telltale可选关键字参数,其中包括:

  

dtype 数据类型,可选

     

阵列所需的数据类型。 如果没有给出,则类型将被确定为在序列中保存对象所需的最小类型。此参数只能用于“向上”数组。

重点是我的。使用np.array([[0], [0]])创建数组时,会得到一个二维整数数组,因为整数是可以包含0的最小数据类型。一旦创建了整数数组,它可能包含整数。如果您尝试插入一个浮点数,它将被转换为您注意到的整数,以便放置在数组中。


如果你想最终在数组中存储浮点数,你需要将数组初始化为一个浮点数组('upcast'它)。这可以通过使用上面提到的dtype参数来完成,或者简单地通过将浮点值放入初始数组(例如0.0而不是整数0)来实现。

import scipy as sp
array_int = sp.array([[0], [0]])
array_float = sp.array([[0.0], [0]])  # Note the extra .0 to make one element a float

array_int[0, 0] = array_int[0, 0] + 0.1
print array_int[0, 0] # 0

array_float[0, 0] = array_float[0, 0] + 0.1
print array_float[0, 0] # 0.1

答案 1 :(得分:3)

亨利凯特已经解释得很好。我只会添加一个技术细节。

与仅仅重新引用integer_for_sure以引用float的{​​{1}}对象的常规赋值相反,从而更改变量的类型,赋值给数组元素,如

integer_for_sure + 0.1

实际上是更详细的语法糖

array_int[0, 0] = array_int[0, 0] + float_operand

(这适用于旧式的类;对于新式的类看起来有点不同但是这个想法保持不变)

每种数组类型的array_int.__setitem__((0,0), array_int.__getitem__((0,0)) + float_operand) 方法对数组的类型执行其value参数的类型转换。实现赋值的实际C代码有点丑陋,涉及自定义预处理器。

另一方面

__setitem__

print array_int[0, 0] + float_operand

即。它从print array_int.__getitem__((0,0)) + float_operand 获取整数值,将其与array_int相加,生成的float_operand对象传递给float。没有print的中间分配,因此没有类型转换。