2012-08-16 29 views
1

我具有由间距xi,yi,zi所描述的立方网格:numpy的3D meshgrid仅作为视图

xi,yi,zi = [linspace(ox,ox+s*d,s) for ox,s,d in zip(origin,size,delta)] 

我也有设置标量值W的到该电网。 W.shape() == size。我想用scipy's linear interpolation,这需要输入:

scipy.interpolate.LinearNDInterpolator(points, values)

参数:

points:花车ndarray,塑造(npoints, ndims)数据点坐标。

values:浮动或复杂的形状,形状(npoints, ...)数据值。

如何从xi,yi,zi创建一个假的一套points(通过神奇广播)?现在我正在创建一个中间数组来馈给插值函数 - 有没有更好的方法?

相关问题Numpy meshgrid in 3D。在这篇文章中的答案实际上创建了网格 - 我只想将其模拟为另一个函数的输入(首选纯粹的numpy解决方案)。

+0

你想要Nxdim数组但是欺骗numpy到不实际分配完整的数组?这是不可能的。你将不得不使用专为常规网格设计的工具,但是我认为在scipy中不存在更高维度的工具。 – seberg 2012-08-16 15:41:15

+0

@Sebastian,你可以模拟更小的数组。例如,如果'x.shape,y.shape =(n,m)',你可以通过采用'[X,Y] ='来创建一个广播的'f(x,y)= x + y' * np.meshgrid(X,Y); S = X + Y',而是'S = x + y [:,np.newaxis]'。有关更多详细信息,请参阅链接问题 – Hooked 2012-08-16 15:51:29

+0

是的,但似乎你想模拟更多的元素,然后实际上是在xi,zi,yi数组中。这是(与stride_tricks)在理论上是可能的。但是由于生成的数组应该是二维的,所以在这种情况下不可能构建它,即使不太可能,scipy也不会在稍后创建副本。 – seberg 2012-08-16 15:55:07

回答

3
>>> xi, yi, zi = [np.arange(3) for i in range(3)] 
>>> xx, yy, zz = np.broadcast_arrays(xi,yi[:,np.newaxis],zi[:,np.newaxis,np.newaxis]) 
>>> xx.shape 
(3, 3, 3) 
>>> xx.strides 
(0, 0, 8) 

您可以看到它没有创建新副本,因为在前两个维度中步幅为0。

我写的这个也是一个立体版本:

def ndmesh(*args): 
    args = map(np.asarray,args) 
    return np.broadcast_arrays(*[x[(slice(None),)+(None,)*i] for i, x in enumera\ 
te(args)]) 
+1

避免为(m * n * l,3)点数组使用任何额外_temporary_数组(不是视图)的唯一方法是使用xx.flat(而不是ravel等)插入未初始化的点数组。 – seberg 2012-08-21 20:25:16

0

我不相信有什么方法可以将某些内容传递给LinearNDInterpolator,而不是完整副本(因为在三维中也没有常规网格的函数)。因此,避免创建完整数组的唯一办法就是在创建这个点数组的时候,我不知道你现在怎么做,所以也许在这方面它已经很有效率了,但我想它可能不值得避免麻烦这个。

其他然后np.mgrid +重塑也许这样的事情可能是一个选项(不是要拼命为n维写的太):反对.repeat功能

# Create broadcastest versions of xi, yi and zi 
# np.broadcast_arrays does not allocate the full arrays 
xi, yi, zi = np.broadcast_arrays(xi[:,None,None], yi[:,None,None], zi[:,None,None]) 

# then you could use .flat to fill a point array: 
points = np.empty((xi.size, 3), dtype=xi.dtype) 
points[:,0] = xi.flat 
points[:,1] = yi.flat 
points[:,2] = zi.flat 

,暂时列在这里创建是不是大于原来的xi等数组。

1

您可以构建在其他的答案解释的类似的方式必要points阵列:

xx, yy, zz = np.broadcast_arrays(xi[:,None,None], yi[None,:,None], zi[None,None,:]) 
points = (xx.ravel(), yy.ravel(), zz.ravel()) 
ip = LinearNDInterpolator(points, data.ravel()) 

但是,如果你有一个规则的网格,然后使用LinearNDInterpolator很可能不是最好的选择,因为它被设计用于分散数据插值。它构造了数据点的Delaunay三角剖分,但在这种情况下,原始数据已经有了一个非常规则的结构,可以更有效地利用。

由于您的网格是矩形的,因此可以将插值建立为三个1-D插值的张量积。 Scipy没有这个内置的(到目前为止),但它很容易做到,看到这个线程:http://mail.scipy.org/pipermail/scipy-user/2012-June/032314.html (使用interp1d而不是pchip来获得1-D插值)