Le maillage de Numpy est très utile pour convertir deux vecteurs en grille de coordonnées. Quelle est la manière la plus simple de l'étendre à trois dimensions? Donc, étant donné trois vecteurs x, y et z, construisez des tableaux 3x3D (au lieu de tableaux 2x2D) qui peuvent être utilisés comme coordonnées.
Voici le code source de 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
C'est assez simple à comprendre. J'ai étendu le modèle à un nombre arbitraire de dimensions, mais ce code n'est en aucun cas optimisé (et pas complètement vérifié non plus), mais vous obtenez ce pour quoi vous payez. J'espère que cela aide:
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)
Numpy (à partir de 1.8 je pense) supporte désormais plus que la génération 2D de grilles de position avec meshgrid . Un ajout important qui m'a vraiment aidé est la possibilité de choisir l'ordre d'indexation (xy
ou ij
pour l'indexation cartésienne ou matricielle respectivement), que j'ai vérifié avec l'exemple suivant:
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_)
Pouvez-vous nous montrer comment vous utilisez np.meshgrid? Il y a de très bonnes chances que vous n'ayez vraiment pas besoin de meshgrid car la diffusion numpy peut faire la même chose sans générer un tableau répétitif.
Par exemple,
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]]
Le fait est que S=X+Y
peut et doit être remplacé par s=x+y[:,np.newaxis]
car ce dernier ne nécessite pas la formation (éventuellement de grandes tailles) de tableaux répétitifs. Il se généralise également aux dimensions supérieures (plus d'axes) facilement. Vous venez d'ajouter np.newaxis
si nécessaire pour effectuer la diffusion si nécessaire.
Voir http://www.scipy.org/EricsBroadcastingDoc pour en savoir plus sur la diffusion numpy.
je pense que ce que tu veux c'est
X, Y, Z = numpy.mgrid[-10:10:100j, -10:10:100j, -10:10:100j]
par exemple.
Voici une version multidimensionnelle de meshgrid que j'ai écrite:
def ndmesh(*args):
args = map(np.asarray,args)
return np.broadcast_arrays(*[x[(slice(None),)+(None,)*i] for i, x in enumerate(args)])
Notez que les tableaux renvoyés sont des vues des données de tableau d'origine, donc la modification des tableaux d'origine affectera les tableaux de coordonnées.
Au lieu d'écrire une nouvelle fonction, numpy.ix _ devrait faire ce que vous voulez.
Voici un exemple tiré de la documentation:
>>> ixgrid = np.ix_([0,1], [2,4])
>>> ixgrid
(array([[0],
[1]]), array([[2, 4]]))
>>> ixgrid[0].shape, ixgrid[1].shape
((2, 1), (1, 2))'