2010-03-25 82 views
3

我想創建一個包含規則間隔點網格的三維座標的列表,每個網格都是一個3元素的元組。我正在尋找建議,以最有效的方式來做到這一點。在C++中,我只需循環三個嵌套循環,每個座標循環一次。在Matlab中,我可能會使用meshgrid函數(這可以在一個命令中完成)。我已經閱讀了Python中的meshgrid和mgrid,並且我也讀過使用numpy的廣播規則更高效。在我看來,將zip函數與numpy廣播規則結合使用可能是最有效的方式,但zip似乎不會在numpy中超載。規則間隔點的三維網格

回答

3

使用ndindex

import numpy as np 
ind=np.ndindex(3,3,2) 
for i in ind: 
    print(i) 

# (0, 0, 0) 
# (0, 0, 1) 
# (0, 1, 0) 
# (0, 1, 1) 
# (0, 2, 0) 
# (0, 2, 1) 
# (1, 0, 0) 
# (1, 0, 1) 
# (1, 1, 0) 
# (1, 1, 1) 
# (1, 2, 0) 
# (1, 2, 1) 
# (2, 0, 0) 
# (2, 0, 1) 
# (2, 1, 0) 
# (2, 1, 1) 
# (2, 2, 0) 
# (2, 2, 1) 
1

多d(大於2)meshgrids,使用numpy.lib.index_tricks.nd_grid像這樣:

import numpy 
grid = numpy.lib.index_tricks.nd_grid() 
g1 = grid[:3,:3,:3] 
g2 = grid[0:1:0.5, 0:1, 0:2] 
g3 = grid[0:1:3j, 0:1:2j, 0:2:2j] 

其中G1具有的x值[0,1,2] 和g2的x值爲[0,.5], ,g3的x值爲[0.0,0.5,1.0](3j定義了步數而不是步增量,詳見documentation

+0

您也可以使用numpy.mgrid,它只是numpy.lib.index_tricks.nd_grid的一個實例。 – rephorm 2012-06-19 17:37:15

1

我會說meshgridmgrid,特別是如果你需要非整數座標。我很驚訝Numpy的廣播規則會更有效率,因爲meshgrid是專門爲您想要解決的問題而設計的。

+1

廣播使得大型電網使用的內存少得多。查看我關於使用'ogrid'獲取更多答案。 – rephorm 2012-06-19 17:46:24

+0

@rephorm:確實(爲您的評論+1)。在過去的兩年裏,我確實瞭解了這一點。 :) – EOL 2012-06-20 05:50:58

3

可以使用ogrid代替meshgrid和mgrid,該ogrid是mgrid的「稀疏」版本。也就是說,只有價值變化的維度被填充。其他的只是廣播。與非稀疏備選方案相比,這對大型網格使用的內存要少得多。

例如:

>>> import numpy as np 
>>> x, y = np.ogrid[-1:2, -2:3] 
>>> x 
array([[-1], 
     [ 0], 
     [ 1]]) 
>>> y 
array([[-2, -1, 0, 1, 2]]) 
>>> x**2 + y**2 
array([[5, 2, 1, 2, 5], 
     [4, 1, 0, 1, 4], 
     [5, 2, 1, 2, 5]]) 
0

這裏是類似於你的C++解決方案,我已經用了完全一樣的目的,一個有效的選項:

import numpy, itertools, collections 
def grid(xmin, xmax, xstep, ymin, ymax, ystep, zmin, zmax, zstep): 
    "return nested tuples of grid-sampled coordinates that include maxima" 
    return collections.deque(itertools.product( 
     numpy.arange(xmin, xmax+xstep, xstep).tolist(), 
     numpy.arange(ymin, ymax+ystep, ystep).tolist(), 
     numpy.arange(zmin, zmax+zstep, zstep).tolist())) 

性能是最好的(在我的測試)當使用a.tolist()時,如上所示,但是您可以使用a.flat並放棄deque()以獲取將緩存內存的迭代器。當然,你也可以使用普通的舊元組()或列表()而不是deque()來輕微地降低性能(在我的測試中)。