2011-08-07 29 views
5

我正在使用Python和Numpy来做一些数据分析。3D数组的高效迭代?

我有一个大的3D矩阵(NxNxN),其中每个单元再次是一个矩阵,此时一个3×3矩阵。调用矩阵data,它看起来像这样:

data[N,N,N,3,3] 

我需要找到所有的3×3矩阵的特征值,和我使用numpy的的eigvals常规,但它需要年龄的事情。现在,我几乎做到这一点:

for i in range(N): 
    for j in range(N): 
     for k in range(N): 
      a = np.linalg.eigvals(data[i,j,k,:,:]) 

对于N = 256,这需要一个小时左右。任何想法如何使这更高效?

非常感谢您的任何建议!

+4

你异形?我怀疑你在eigvals上花费的时间比你迭代的要多得多。 – matt

+3

eigvals大约需要三个数量级不再受我的timeit计算,所以我不认为改变迭代会影响到什么。 – DSM

回答

5

itertools.product比嵌套循环更漂亮,美观。但我认为它不会让你的代码更快。我的测试表明迭代不是你的瓶颈。

>>> bigdata = numpy.arange(256 * 256 * 256 * 3 * 3).reshape(256, 256, 256, 3, 3) 
>>> %timeit numpy.linalg.eigvals(bigdata[100, 100, 100, :, :]) 
10000 loops, best of 3: 52.6 us per loop 

因此低估:

>>> .000052 * 256 * 256 * 256/60 
14.540253866666665 

这是我的计算机,这是非常新的最少14分钟。让我们看看循环需要多久...

>>> def just_loops(N): 
...  for i in xrange(N): 
...   for j in xrange(N): 
...    for k in xrange(N): 
...     pass 
... 
>>> %timeit just_loops(256) 
1 loops, best of 3: 350 ms per loop 

正如帝斯曼表示的那样,数量级较小。即使单独切片的阵列的工作更加充实:

>>> def slice_loops(N, data): 
...  for i in xrange(N): 
...   for j in xrange(N): 
...    for k in xrange(N): 
...     data[i, j, k, :, :] 
... 
>>> %timeit slice_loops(256, bigdata) 
1 loops, best of 3: 33.5 s per loop 
+0

非常详尽的答案,谢谢!从你的测试看来,确实看起来没有太多的工作要做得更快。 – digitaldingo

3

我敢肯定有在与NumPy做到这一点的好办法,但在一般情况下,itertools.product比超过范围嵌套循环更快。

from itertools import product 

for i, j, k in product(xrange(N), xrange(N), xrange(N)): 
    a = np.linalg.eigvals(data[i,j,k,:,:]) 
+0

在这种情况下 - 由于N是如此之小 - 事实上,我发现,循环开销是大约两倍的产品环比与嵌套的范围大。我仍然更喜欢产品的方法,因为它更平坦,而且这里的开销可以忽略不计。 – DSM

+0

这很有趣。在我看来,创建65536 + 256个内部列表会更慢(尽管我没有想到它会产生巨大的影响)。 – agf

2

,因为所有的计算都是独立的,你可以用多模块来加速计算,如果你有一个多核处理器。