Ich versuche, den Parameterraum einer 6-Parameter-Funktion zu durchlaufen, um ihr numerisches Verhalten zu untersuchen, bevor ich versuche, etwas Komplexes damit zu tun, also suche ich nach einem effizienten Weg, dies zu tun.
Meine Funktion verwendet Float-Werte bei einem 6-Dim-Numpy-Array als Eingabe. Was ich anfangs versuchte, war Folgendes:
Zuerst habe ich eine Funktion erstellt, die 2 Arrays verwendet und aus den beiden Arrays ein Array mit allen Wertekombinationen generiert
from numpy import *
def comb(a,b):
c = []
for i in a:
for j in b:
c.append(r_[i,j])
return c
Dann habe ich reduce()
das auf m Kopien desselben Arrays angewendet :
def combs(a,m):
return reduce(comb,[a]*m)
Und dann bewerte ich meine Funktion folgendermaßen:
values = combs(np.arange(0,1,0.1),6)
for val in values:
print F(val)
Das funktioniert, aber es ist zu langsam. Ich weiß, dass der Raum der Parameter riesig ist, aber das sollte nicht so langsam sein. Ich habe in diesem Beispiel nur 10 6 (eine Million) Punkte abgetastet und es dauerte mehr als 15 Sekunden, um das Array zu erstellen values
.
Kennen Sie einen effizienteren Weg, dies mit Numpy zu tun?
Ich kann die Art und Weise ändern, wie die Funktion F
ihre Argumente verwendet, wenn dies erforderlich ist.
quelle
Antworten:
numpy
Bietet in der neueren Version von (> 1.8.x)numpy.meshgrid()
eine viel schnellere Implementierung:@ pvs Lösung
numpy.meshgrid()
Früher war es nur 2D, jetzt ist es ND-fähig. In diesem Fall 3D:Beachten Sie, dass die Reihenfolge des Endergebnisses geringfügig abweicht.
quelle
np.stack(np.meshgrid([1, 2, 3], [4, 5], [6, 7]), -1).reshape(-1, 3)
wird die richtige Bestellung gebenHier ist eine reine Numpy-Implementierung. Es ist ungefähr 5 × schneller als die Verwendung von itertools.
quelle
from sklearn.utils.extmath import cartesian
TypeError: slice indices must be integers or None or have an __index__ method
geworfen voncartesian(arrays[1:], out=out[0:m,1:])
itertools.combinations ist im Allgemeinen der schnellste Weg, um Kombinationen aus einem Python-Container abzurufen (wenn Sie tatsächlich Kombinationen wünschen, dh Arrangements OHNE Wiederholungen und unabhängig von der Reihenfolge; das scheint Ihr Code nicht zu tun, aber ich kann nicht Sagen Sie, ob dies daran liegt, dass Ihr Code fehlerhaft ist oder dass Sie die falsche Terminologie verwenden.
Wenn Sie etwas anderes als Kombinationen möchten, können Ihnen andere Iteratoren in itertools
product
oderpermutations
besser dienen. Zum Beispiel sieht Ihr Code ungefähr so aus wie:Alle diese Iteratoren ergeben Tupel, keine Listen oder Numpy-Arrays. Wenn Ihr F also wählerisch ist, ein bestimmtes Numpy-Array zu erhalten, müssen Sie den zusätzlichen Aufwand akzeptieren, bei jedem Schritt eines zu erstellen oder zu löschen und neu zu füllen.
quelle
Sie können so etwas tun
was gibt
quelle
Die folgende Numpy-Implementierung sollte ca. 2x die Geschwindigkeit der gegebenen Antwort:
quelle
np.indices((n,...,n)).reshape(k,-1).T
ist dies ausreichend.Es sieht so aus, als ob Sie möchten, dass ein Raster Ihre Funktion bewertet. In diesem Fall können Sie Folgendes verwenden
numpy.ogrid
(offen) odernumpy.mgrid
(konkretisiert):quelle
Sie können verwenden
np.array(itertools.product(a, b))
quelle
Hier ist noch eine andere Möglichkeit, reines NumPy zu verwenden, keine Rekursion, kein Listenverständnis und keine expliziten for-Schleifen. Es ist ungefähr 20% langsamer als die ursprüngliche Antwort und basiert auf np.meshgrid.
Beispielsweise,
gibt
quelle
Für eine reine Numpy-Implementierung des kartesischen Produkts von 1D-Arrays (oder flachen Python-Listen) verwenden Sie einfach
meshgrid()
die Achsen, rollen Sie mittranspose()
und formen Sie die gewünschte Ausgabe neu:Beachten Sie, dass sich die Konvention der letzten Achse am schnellsten ändert ("C-Stil" oder "Zeilenmajor").
Wenn Sie die erste Achse am schnellsten ändern möchten ("FORTRAN-Stil" oder "Spalten-Major"), ändern Sie einfach den
order
Parameterreshape()
wie folgt:reshape((-1, N), order='F')
quelle
Pandas
merge
bietet eine naive, schnelle Lösung für das Problem:quelle