【发布时间】:2010-12-22 02:23:22
【问题描述】:
Numpy 的 meshgrid 对于将两个向量转换为坐标网格非常有用。将其扩展到三个维度的最简单方法是什么?所以给定三个向量 x、y 和 z,构造 3x3D 数组(而不是 2x2D 数组)作为坐标。
【问题讨论】:
Numpy 的 meshgrid 对于将两个向量转换为坐标网格非常有用。将其扩展到三个维度的最简单方法是什么?所以给定三个向量 x、y 和 z,构造 3x3D 数组(而不是 2x2D 数组)作为坐标。
【问题讨论】:
您可以通过更改顺序来实现:
import numpy as np
xx = np.array([1,2,3,4])
yy = np.array([5,6,7])
zz = np.array([9,10])
y, z, x = np.meshgrid(yy, zz, xx)
【讨论】:
Numpy(我认为从 1.8 开始)现在支持使用meshgrid 生成高于 2D 的位置网格。一个真正帮助我的重要补充是能够选择索引顺序(xy 或 ij 分别用于笛卡尔或矩阵索引),我通过以下示例进行了验证:
import numpy as np
x_ = np.linspace(0., 1., 10)
y_ = np.linspace(1., 2., 20)
z_ = np.linspace(3., 4., 30)
x, y, z = np.meshgrid(x_, y_, z_, indexing='ij')
assert np.all(x[:,0,0] == x_)
assert np.all(y[0,:,0] == y_)
assert np.all(z[0,0,:] == z_)
【讨论】:
assert 只是检查沿 x、y 和 z 轴的索引是否等于预期的 *_ 变量。不需要。
numpy.ix_ 应该做你想做的,而不是写一个新函数。
这是文档中的一个示例:
>>> ixgrid = np.ix_([0,1], [2,4])
>>> ixgrid
(array([[0],
[1]]), array([[2, 4]]))
>>> ixgrid[0].shape, ixgrid[1].shape
((2, 1), (1, 2))'
【讨论】:
这是我编写的多维网格网格:
def ndmesh(*args):
args = map(np.asarray,args)
return np.broadcast_arrays(*[x[(slice(None),)+(None,)*i] for i, x in enumerate(args)])
注意返回的数组是原始数组数据的视图,所以改变原始数组会影响坐标数组。
【讨论】:
这里是meshgrid的源码:
def meshgrid(x,y):
"""
Return coordinate matrices from two coordinate vectors.
Parameters
----------
x, y : ndarray
Two 1-D arrays representing the x and y coordinates of a grid.
Returns
-------
X, Y : ndarray
For vectors `x`, `y` with lengths ``Nx=len(x)`` and ``Ny=len(y)``,
return `X`, `Y` where `X` and `Y` are ``(Ny, Nx)`` shaped arrays
with the elements of `x` and y repeated to fill the matrix along
the first dimension for `x`, the second for `y`.
See Also
--------
index_tricks.mgrid : Construct a multi-dimensional "meshgrid"
using indexing notation.
index_tricks.ogrid : Construct an open multi-dimensional "meshgrid"
using indexing notation.
Examples
--------
>>> X, Y = np.meshgrid([1,2,3], [4,5,6,7])
>>> X
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
>>> Y
array([[4, 4, 4],
[5, 5, 5],
[6, 6, 6],
[7, 7, 7]])
`meshgrid` is very useful to evaluate functions on a grid.
>>> x = np.arange(-5, 5, 0.1)
>>> y = np.arange(-5, 5, 0.1)
>>> xx, yy = np.meshgrid(x, y)
>>> z = np.sin(xx**2+yy**2)/(xx**2+yy**2)
"""
x = asarray(x)
y = asarray(y)
numRows, numCols = len(y), len(x) # yes, reversed
x = x.reshape(1,numCols)
X = x.repeat(numRows, axis=0)
y = y.reshape(numRows,1)
Y = y.repeat(numCols, axis=1)
return X, Y
这很容易理解。我将模式扩展到任意数量的维度,但这段代码绝不是优化的(也没有彻底检查错误),但你得到了你所付出的。希望对您有所帮助:
def meshgrid2(*arrs):
arrs = tuple(reversed(arrs)) #edit
lens = map(len, arrs)
dim = len(arrs)
sz = 1
for s in lens:
sz*=s
ans = []
for i, arr in enumerate(arrs):
slc = [1]*dim
slc[i] = lens[i]
arr2 = asarray(arr).reshape(slc)
for j, sz in enumerate(lens):
if j!=i:
arr2 = arr2.repeat(sz, axis=j)
ans.append(arr2)
return tuple(ans)
【讨论】:
return tuple(ans[::-1]) 替换return 语句可以解决这个问题。
你能告诉我们你是如何使用 np.meshgrid 的吗?很有可能你真的不需要 meshgrid,因为 numpy 广播可以做同样的事情而不会生成重复的数组。
例如,
import numpy as np
x=np.arange(2)
y=np.arange(3)
[X,Y] = np.meshgrid(x,y)
S=X+Y
print(S.shape)
# (3, 2)
# Note that meshgrid associates y with the 0-axis, and x with the 1-axis.
print(S)
# [[0 1]
# [1 2]
# [2 3]]
s=np.empty((3,2))
print(s.shape)
# (3, 2)
# x.shape is (2,).
# y.shape is (3,).
# x's shape is broadcasted to (3,2)
# y varies along the 0-axis, so to get its shape broadcasted, we first upgrade it to
# have shape (3,1), using np.newaxis. Arrays of shape (3,1) can be broadcasted to
# arrays of shape (3,2).
s=x+y[:,np.newaxis]
print(s)
# [[0 1]
# [1 2]
# [2 3]]
关键是S=X+Y可以而且应该被s=x+y[:,np.newaxis]替换,因为
后者不需要形成(可能很大的)重复阵列。它还可以轻松推广到更高维度(更多轴)。您只需在需要的地方添加np.newaxis 即可根据需要进行广播。
有关 numpy 广播的更多信息,请参阅http://www.scipy.org/EricsBroadcastingDoc。
【讨论】:
我认为你想要的是
X, Y, Z = numpy.mgrid[-10:10:100j, -10:10:100j, -10:10:100j]
例如。
【讨论】: