2013-07-26 23 views
4

这是一个小代码,它演示了我得到的错误。numpy缺少属性取决于数组大小

import numpy as np 

r=4.0 
L=20.0 
ratio = 4*np.pi/3.0 * (r/L)**3 

for i in range(5, 16): 
    n = 10**i 
    m = int(ratio * n) 
    print i,n,m 

    ip = np.random.random_integers(100, size=(n,3))  
    jp = np.random.random_integers(100, size=(m,3)) 

    a = np.expand_dims(ip, -1) == jp.T 
    b = np.where(a.all(axis=1).any(axis=1))[0] 

我得到以下输出:

5 100000 3351 
6 1000000 33510 
Traceback (most recent call last): 
    File "example.py", line 16, in <module> 
    b = np.where(a.all(axis=1).any(axis=1))[0] 
AttributeError: 'bool' object has no attribute 'all' 

任何人都知道是怎么回事?

另外,一个合理的快速方式索引ip中元素的位置也可以。我可能会从第二个解决方案here

+1

其中'i == 5'数组'a'的大小已经在10亿个元素的数量级上,其中'i == 6'是它的1000亿个元素(如果是'bool',100 GB的数据)。这些非常大的阵列是故意的吗? – Daniel

+0

大小是有意的,他们是一个相当密集的计算网格。在'i == 6'' np.expand_dims(ip,-1).nbytes == 24000000'这应该是合理的,不是? – user1984528

+0

是的,这是合理的,但是你用'jp.T'来广播这个大小来表示'a'的大小。以GB为单位打印a.nbytes/1E9'。 – Daniel

回答

0

您正在广播ip针对jp创建非常大的数组。当i==6你有一个100GB的阵列。

一种解决方案是循环阵列之上:

for i in range(2,6): 
    t=time.time() 
    n = 10**i+1 
    m = int(ratio * n) 
    print i,n,m 

    ip = np.random.random_integers(10, size=(n,3)) 
    jp = np.random.random_integers(10, size=(m,3)) 

    chunksize=10000 
    if chunksize>ip.shape[0]: 
     chunksize=ip.shape[0] 
    span=ip.shape[0]/chunksize 
    remainder=(ip.shape[0]-span*chunksize) 

    out=[] 
    start=0 
    for n in xrange(span): 
     end=start+chunksize 
     a = np.expand_dims(ip[start:end], -1) == jp.T 
     b = np.where(a.all(axis=1).any(axis=1))[0] 
     out.append(b+start) 
     start+=chunksize 

    if remainder!=0: 
     a = np.expand_dims(ip[-remainder:], -1) == jp.T 
     b = np.where(a.all(axis=1).any(axis=1))[0] 
     out.append(b+end) 

    end=np.sort(np.concatenate(out)) 
    print time.time()-t,end.shape 

时间为约10秒i==6所以i==7将需要约20分钟。