Ich habe eine Funktion, die eine Liste (von Strings) akzeptiert. Es führt eine Verarbeitung auf dieser Liste durch und gibt eine andere Liste von Strings zurück, möglicherweise von kürzerer Länge.Funktion auf jede Liste in einer Reihe von Listen anwenden
Jetzt habe ich eine Reihe von Eingabe-Listen von Strings. Ich möchte diese Transformationsfunktion auf jede Liste in meinem Array anwenden.
Von was für eine Suche ich bisher gemacht habe, es schien wie vectorize oder apply_along_axis könnte gute Kandidaten sein, aber keiner funktioniert wie erwartet.
Ich möchte das so effizient wie möglich tun. Letztendlich wird das Eingabe-Array in der Größenordnung von 100K Listen enthalten.
Ich nehme an, ich könnte über die numpy-Array in einer for
Schleife, dann append
jede Ausgabeliste in ein neues Ausgabe-Array einzeln nacheinander, aber das scheint schrecklich ineffizient.
Hier ist was ich versucht habe. Zu Testzwecken habe ich eine dumbed-down-Transformationsfunktion erstellt und das Eingabearray enthält nur 3 Listen.
def my_func(l):
# accepts list, returns another list
# dumbed down list transformation function
# for testing, just return the first 2 elems of original list
return l[0:2]
test_arr = np.array([['the', 'quick', 'brown', 'fox'], ['lorem', 'ipsum'], ['this', 'is', 'a', 'test']])
np.apply_along_axis(my_func, 0, test_arr)
Out[51]: array([['the', 'quick', 'brown', 'fox'], ['lorem', 'ipsum']], dtype=object)
# Rather than applying item by item, this returns the first 2 elements of the entire outer array!!
# Expected:
# array([['the', 'quick'], ['lorem', 'ipsum'], ['this', 'is']])
# Attempt 2...
my_func_vec = np.vectorize(my_func)
my_func_vec(test_arr)
Ergebnis:
Traceback (most recent call last):
File "<ipython-input-56-f9bbacee645c>", line 1, in <module>
my_func_vec(test_arr)
File "C:\Users\Tony\Anaconda2\lib\site-packages\numpy\lib\function_base.py", line 2218, in __call__
return self._vectorize_call(func=func, args=vargs)
File "C:\Users\Tony\Anaconda2\lib\site-packages\numpy\lib\function_base.py", line 2291, in _vectorize_call
copy=False, subok=True, dtype=otypes[0])
ValueError: cannot set an array element with a sequence
Diese oft diskutiert worden ist. Weder "vektorisieren" noch "anwenden" ...'wird die' Effizienz' verbessern. Sie müssen Ihre Funktion immer noch auf jeder Liste aufrufen und die Ergebnisse in einem Array oder einer Liste zusammenfassen. Im Großen und Ganzen läuft die Funktion 100k mal so langsam, nicht das Iterationsframework. – hpaulj
In früheren Tests habe ich festgestellt, dass 'np.frompyfunc' ein gutes Werkzeug zum Iterieren von Objekt-Arrays ist. – hpaulj
Eigentlich dachte ich genau das Gleiche, entschied mich aber, die Frage zu beantworten, anstatt zu sagen, wie ich es machen würde. Aber dann habe ich es getestet und aus irgendeinem Grund war die Vektorisierung 10x schneller als Listenverständnis oder die map() Funktion ... irgendeine Idee warum? – dnalow