Diciamo che ho una funzione f che può assumere le coordinate come parametro e restituisce un intero (f (x) in questo caso). Le coordinate possono essere multidimensionali e hanno la forma di una lista. Il mio obiettivo è riempire una matrice numpy con tutti i valori tra due coordinate. Ho cercato di creare un elenco di tutti gli indici possibili e usarlo come input per la funzione vettoriale.Genera un array n-dimensionale di coordinate in numpy
Ecco il mio codice per 2 coordinate tridimensionali:
import itertools
import numpy
def index_array(lower_corner, upper_corner):
x_range = range(lower_corner[0], upper_corner[0])
y_range = range(lower_corner[1], upper_corner[1])
return numpy.array(list(itertools.product(x_range, y_range)))
print(index_array([2, -2], [5, 3]))
Questo restituirà la lista degli indici come previsto:
[[ 2 -2]
[ 2 -1]
[ 2 0]
[ 2 1]
[ 2 2]
[ 3 -2]
[ 3 -1]
[ 3 0]
[ 3 1]
[ 3 2]
[ 4 -2]
[ 4 -1]
[ 4 0]
[ 4 1]
[ 4 2]]
E qui è il mio tentativo per n dimensioni:
import itertools
import numpy
def f(x):
# dummy function
return x + 5
def index_array(lower_corner, upper_corner):
# returns all indices between two n-dimensional points
range_list = []
for n in range(len(lower_corner)):
range_list.append(range(lower_corner[n], upper_corner[n]))
return numpy.array(list(itertools.product(*range_list)))
lower_corner = numpy.array([2, -2])
upper_corner = numpy.array([5, 3])
indices = index_array(lower_corner, upper_corner)
vect_func = numpy.vectorize(f)
results = vect_func(indices)
print(results)
Mentre funziona è piuttosto lento e necessita di enormi quantità di memoria. È possibile scrivere questo in modo più efficiente? Potrei pensare a usare numpy.meshgrid ma non so come lo userei.
Ehm, sto già usando 'product' da' itertools'. È nascosto nel ritorno della seconda funzione: D. Ma grazie per il loop più compatto! – Gnarflord
Puoi cambiare 'range (r [0], r [1])' con 'range (* r)'. inoltre stai usando un compendio di lista che viene immediatamente decompresso. Potresti usare invece un gen exp (ad esempio '* (range (* r) ...)' sostituendo '[]' con '()') ed evita di creare quell'elenco temporaneo. – Bakuriu
@Bakuriu Funziona perfettamente, grazie per averlo indicato. Una soluzione molto più efficiente e concisa credo. – Psidom