2014-01-31 107 views
2

我想与numba使用numpy,但我得到奇怪的结果,同时尝试访问或设置一些值为浮点型数组使用浮点型索引转换为int 。 检查这个基本功能。在Python/Numba中访问数组给出奇怪的结果

@numba.jit("void(f8[:,::1],f8[:,::1])") 
def test(table, index): 
x,y = int(index[0,0]), int(index[1,0) 
table[y,x] = 1.0 
print index[0,0], index[1,0], x,y 
print table 
print table[y,x] 

table = np.zeros((5,5), dtype = np.float32) 
index = np.random.ranf(((2,2)))*5 
test(table, index) 

结果:

index[0,0] = 1.34129550525 index[1,0] = 0.0656177324359 x = 1 y = 0  
table[0,1] = 1.0 
table [[ 0.  0.  1.875 0.  0. ] 
     [ 0.  0.  0.  0.  0. ] 
     [ 0.  0.  0.  0.  0. ] 
     [ 0.  0.  0.  0.  0. ] 
     [ 0.  0.  0.  0.  0. ]] 

为什么我能在这个表中的1.875,而不是1.0?这是一个基本的例子,但我正在与大数组一起工作,它给了我很多错误。我知道我可以将索引转换为np.int32并更改@ numba.jit(“void(f8 [:,:: 1],f8 [:,1])”)@ numba.jit (“void(f8 [:,:: 1],i4 [:,:: 1])”),这是工作正常,但我想你想明白为什么这是行不通的。 从python解析类型到C++时它是一个问题?

感谢您帮助

+0

没有在JIT的F8声明和初始化np.float32之间的差异? 1.875不在x = 1处。 顺便说一句,为什么它被标记为C++? – Joky

+0

@Joky C++标签是一个错误的抱歉。是的,它与np.float64一起工作。 但对于像1.0这样的数字应该浮动32或浮动64有所作为? –

+0

既然您标记了C++;):问题是该表是一个指向double的指针,指向一个float数组。在位置1重叠位置3/4的浮点数(2倍大)和在两个浮点数上的双精度编码没有任何意义。顺便说一句,这是一个猜测,因为我不知道什么是numba生成的代码。编辑:unutbu下面解释清楚。 – Joky

回答

4
In [198]: np.float64(1.0).view((np.float32,2)) 
Out[198]: array([ 0. , 1.875], dtype=float32) 

所以当

table[y,x] = 1.0 

写入np.float64(1.0)tabletable视图中的数据为np.float32和其解释为0和1.875。

注意,在0索引位置[0,1]显示出来,并1.875显示出来在索引位置[0,2],而分配发生在[y,x] = [0,1]

您可以通过改变

@numba.jit("void(f8[:,::1],f8[:,::1])") 

修复D型不匹配

@numba.jit("void(f4[:,::1],f8[:,::1])") 

这些是8个字节np.float64(1.0)

In [201]: np.float64(1.0).tostring() 
Out[201]: '\x00\x00\x00\x00\x00\x00\xf0?' 

而且4个字节时'\x00\x00\xf0?'被解释为np.float32你得到1.875:

In [205]: np.fromstring('\x00\x00\xf0?', dtype='float32') 
Out[205]: array([ 1.875], dtype=float32) 
+0

非常感谢。也许这是一个愚蠢的问题,但为什么np.float64和np.float32之间的区别? –

+0

'np.float64'表示一个64位(8字节)的浮点数。 'np.float32'代表一个32位(4字节)的浮点数。 'np.float(1。0)'占用8个字节。如果将它写入'table',则覆盖8个字节。当“table”被打印时,它将其基础数据解释为4字节的浮点数,所以你写了'table'中的2个值(浮点数)。 – unutbu

+0

好吧,我知道float64是8字节和float32 4个字节。但我认为字节数只是改变了你可以写的最大数量。不是这个数字的写法。例如np.int32(1).tostring()给出'\ x01 \ x00 \ x00 \ x00'和np.int64(1).tostring()给出'\ x01 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00',即使浮点数和整数不同,我认为np.float64会给 '\ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x80?' –