2016-04-26 59 views
3

令我惊讶的是,我发现,从NumPy结构化数组读取和写入NumPy结构化数组似乎是线性大小的数组。读/写NumPy结构化数组非常缓慢,线性大小缓慢

由于这看起来很不对,我想知道,如果我在这里做错了什么,或者如果可能有错误。

下面是一些示例代码:

def test(): 
    A = np.zeros(1, dtype=[('a', np.int16), ('b', np.int16, (1,100))]) 
    B = np.zeros(1, dtype=[('a', np.int16), ('b', np.int16, (1,10000))]) 

    C = [{'a':0, 'b':[0 for i in xrange(100)]}] 
    D = [{'a':0, 'b':[0 for i in xrange(10000)]}] 

    for i in range(100): 
     A[0]['a'] = 1 
     B[0]['a'] = 1 

     B['a'][0] = 1 
     x = A[0]['a'] 
     x = B[0]['a'] 

     C[0]['a'] = 1 
     D[0]['a'] = 1 

行剖析得出以下结果:

Total time: 5.28901 s, Timer unit: 1e-06 s 
Function: test at line 454 


Line #  Hits   Time Per Hit % Time Line Contents 
============================================================== 
    454           @profile 
    455           def test(): 
    456            
    457   1   10  10.0  0.0  A = np.zeros(1, dtype=[('a', np.int16), ('b', np.int16, (1,100))]) 
    458   1   13  13.0  0.0  B = np.zeros(1, dtype=[('a', np.int16), ('b', np.int16, (1,10000))]) 
    459           
    460  101   39  0.4  0.0  C = [{'a':0, 'b':[0 for i in xrange(100)]}] 
    461  10001   3496  0.3  0.1  D = [{'a':0, 'b':[0 for i in xrange(10000)]}] 
    462           
    463  101   54  0.5  0.0  for i in range(100): 
    464  100  20739 207.4  0.4   A[0]['a'] = 1 
    465  100  1741699 17417.0  32.9   B[0]['a'] = 1 
    466             
    467  100  1742374 17423.7  32.9   B['a'][0] = 1 
    468  100  20750 207.5  0.4   x = A[0]['a'] 
    469  100  1759634 17596.3  33.3   x = B[0]['a'] 
    470           
    471  100   123  1.2  0.0   C[0]['a'] = 1 
    472  100   76  0.8  0.0   D[0]['a'] = 1 

正如你所看到的,我甚至不访问较大的阵列(尽管大小的10.000其实真的很小..)。顺便说一句:相同的行为形状=(10000,1),而不是(1,10000)。

任何想法?

解释的结构化阵列类型的字典的列表,并且比较向内置函数,有独立尺寸的预期的计算成本(见C和d)

NumPy的版1.10.1。

+1

我无法在1.8.1上重现您的结果。也许这是自那时起引入的一个bug,或者他们改变了语义或其他东西。 – user2357112

+0

@ user2357112按照你的答案,我更新到NumPy 1.11.0并再次检查。现在一切都像魅力一样运行。所以可能有一个错误。如果您发布答案,我可以将其标记为正确。谢谢。 – user2532323

回答

2

这是一个与NumPy 1.10.1上的结构化阵列。问题日志中的对话似乎表明它已修复所有更新的NumPy版本,包括1.10.2和1.11.0。

更新NumPy应该让问题消失。

0

随着ipythontimeit我得到基本相同的时间AB

In [30]: timeit A[0]['a']=1 
1000000 loops, best of 3: 1.9 µs per loop 

In [31]: timeit B[0]['a']=1 
1000000 loops, best of 3: 1.87 µs per loop 

In [32]: timeit B['a'][0]=1 
1000000 loops, best of 3: 554 ns per loop 

In [33]: timeit x=A[0]['a'] 
1000000 loops, best of 3: 1.74 µs per loop 

In [34]: timeit x=B[0]['a'] 
1000000 loops, best of 3: 1.73 µs per loop 

即使我创建B有100条记录,时间不会改变

In [39]: timeit B['a']=1 # set 100 values at once 
1000000 loops, best of 3: 1.08 µs per loop 

In [40]: timeit B['a'][10]=1 
1000000 loops, best of 3: 540 ns per loop 

In [41]: B.shape # 2Mb size 
Out[41]: (100,) 

即使设置'b'字段的10000个数值并不昂贵

In [46]: B['b'].shape 
Out[46]: (100, 1, 10000) 

In [47]: B['b'][:,:,:100]=1 

In [48]: timeit B['b'][:,:,:100]=1 
100000 loops, best of 3: 10.7 µs per loop 

In [49]: B['b'].sum() 
Out[49]: 10000 

In [50]: np.__version__ 
Out[50]: '1.11.0'