Siatka Numpy'ego jest bardzo przydatna do konwersji dwóch wektorów na siatkę współrzędnych. Jaki jest najprostszy sposób rozszerzenia tego na trzy wymiary? Tak więc biorąc pod uwagę trzy wektory x, y i z, skonstruuj tablice 3x3D (zamiast tablic 2x2D), które mogą być użyte jako współrzędne.Numpy meshgrid w 3D
Odpowiedz
Oto kod źródłowy 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
Jest to dość proste do zrozumienia. Rozszerzyłem wzorzec do dowolnej liczby wymiarów, ale ten kod nie jest w żaden sposób zoptymalizowany (i nie został dokładnie sprawdzony pod kątem błędów), ale dostajesz to, za co płacisz. Nadzieję, że to pomaga:
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)
myślę co chcesz to
X, Y, Z = numpy.mgrid[-10:10:100j, -10:10:100j, -10:10:100j]
na przykład.
Dzięki, ale to nie jest całkiem co Potrzebuję - meshgrid w rzeczywistości wykorzystuje wartości wektorów do generowania tablicy 2D, a wartości mogą być nieregularnie rozmieszczone. – astrofrog
Czy możesz pokazać nam, jak używasz np.meshgrid? Istnieje bardzo duża szansa, że naprawdę nie potrzebujesz meshgrid, ponieważ rozgłaszanie numpy może zrobić to samo, bez generowania powtarzalnej tablicy.
Przykładowo
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]]
Chodzi o to, że S=X+Y
mogą i powinny być zastąpione s=x+y[:,np.newaxis]
ponieważ ten nie wymaga dużych (ewentualnie) powtarzające się tablice być utworzona. Generalizuje również łatwo wyższe wymiary (więcej osi). Po prostu dodajesz np.newaxis
tam, gdzie jest to konieczne, aby odpowiednio nadawać.
Więcej informacji na temat transmisji numpy można znaleźć pod numerem telefonu http://www.scipy.org/EricsBroadcastingDoc.
Zamiast pisać nową funkcję, numpy.ix_ powinien robić, co chcesz.
Oto przykład z dokumentacji:
>>> ixgrid = np.ix_([0,1], [2,4])
>>> ixgrid
(array([[0],
[1]]), array([[2, 4]]))
>>> ixgrid[0].shape, ixgrid[1].shape
((2, 1), (1, 2))'
Byłoby miło, gdybyś mógł powiedzieć, jak? ... –
Oto wielowymiarowa wersja meshgrid że napisałem:
def ndmesh(*args):
args = map(np.asarray,args)
return np.broadcast_arrays(*[x[(slice(None),)+(None,)*i] for i, x in enumerate(args)])
Należy zauważyć, że zwracane tablice są widoki oryginalnych danych tablicowych, więc zmiana oryginalnych tablic wpłynie na tablice współrzędnych.
załatwił mi sprawę, wielkie dzięki! – somada141
Numpy (od wersji 1.8 myślę) obsługuje teraz wyższe 2D generacji siatki pozycji z meshgrid. Jeden ważny dodatek, który naprawdę pomógł mi to zdolność do wyboru kolejności indeksowania (albo xy
lub ij
dla kartezjańskiego lub matrycy indeksowania odpowiednio), które weryfikowane z poniższym przykładzie:
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_)
W przypadku siatki siatkowej 3d, używając próbki podobnej do tej podanej w numpy doc dla metody meshgrib, zwracałoby to Z, Y, X zamiast X, Y, Z. Zastąpienie instrukcji return przez 'return tuple (ans [:: - 1])' może to naprawić. – levesque
@Paul, jeśli długość tablicy x lub y jest długa, wówczas komenda x.repeat() ulega awarii i wysyła błąd pamięci. Czy istnieje sposób na uniknięcie tego błędu? – Dalek
@Dalek Jak długo są tablice? Czy to możliwe, że zabraknie Ci pamięci? Na przykład, jeśli są 3 tablice, po 4096 wpisów, a każdy wpis zawiera podwójne (tj. 8 bajtów), wtedy dla samych wpisów potrzebujemy (8 * 4 * 2 ** 10) ** 3 bajty = 2 ** 45 bajtów = 32 * 2 ** 40 bajtów = 32 TB pamięci, co jest oczywiście gigantyczne. Mam nadzieję, że tutaj się nie pomyliłem. –