Ich berechne die häufigste Zahl in einem Vektor von int8
s. Numba beschwert, wenn ich einen Zähler Reihe von int
s einzurichten:Array von Ints in Numba
@jit(nopython=True)
def freq_int8(y):
"""Find most frequent number in array"""
count = np.zeros(256, dtype=int)
for val in y:
count[val] += 1
return ((np.argmax(count)+128) % 256) - 128
es aufrufen ich die folgende Fehlermeldung erhalten:
TypingError: Invalid usage of Function(<built-in function zeros>) with parameters (int64, Function(<class 'int'>))
Wenn ich dtype=int
löschen es funktioniert und ich eine anständige Beschleunigung. Ich bin jedoch verwirrt, warum das Deklarieren eines Arrays von int
s nicht funktioniert. Gibt es einen bekannten Workaround, und wäre hier ein Effizienzgewinn sinnvoll?
Hintergrund: Ich versuche Mikrosekunden von etwas schwerfällig Code zu rasieren. Ich bin besonders verletzt von numpy.median
, und habe in Numba untersucht, aber ich kämpfe um median
zu verbessern. Die häufigste Nummer zu finden ist eine akzeptable Alternative zu median
, und hier konnte ich etwas Leistung gewinnen. Der obige Numba-Code ist auch schneller als numpy.bincount
.
Update: Nach der Eingabe in der Antwort akzeptiert, hier ist eine Implementierung von median
für int8
Vektoren. Es ist in etwa eine Größenordnung schneller als numpy.median
:
@jit(nopython=True)
def median_int8(y):
N2 = len(y)//2
count = np.zeros(256, dtype=np.int32)
for val in y:
count[val] += 1
cs = 0
for i in range(-128, 128):
cs += count[i]
if cs > N2:
return float(i)
elif cs == N2:
j = i+1
while count[j] == 0:
j += 1
return (i + j)/2
der Leistungsunterschied Überraschenderweise ist noch größer für kurze Vektoren, die offensichtlich auf Overhead in numpy
Vektoren:
>>> a = np.random.randint(-128, 128, 10)
>>> %timeit np.median(a)
The slowest run took 7.03 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 20.8 µs per loop
>>> %timeit median_int8(a)
The slowest run took 11.67 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 593 ns per loop
Dieser Aufwand ist so groß, Ich frage mich, ob etwas nicht stimmt.
Das ist also was _mode_ bedeutet!Ja, ich verstehe den Unterschied zum Median, aber in meinem speziellen Anwendungsfall ist der Modus wahrscheinlich angemessener als der Median. Ihr Vorschlag, dtype = np.int32 zu verwenden, funktioniert in der Tat und führte zu weiteren 30% Beschleunigung. Was "bincount" angeht, funktioniert das auch wie gewünscht, ist aber ungefähr halb so schnell wie die numba-Version. – DNF
@DNF numba ist in der Tat schneller als bilcount, aber beachte, dass der erste Aufruf von numba immer langsamer ist (außer du rufst ihn mit sehr großen Arrays an). Wenn Sie die Funktion so definieren, dass sie nur einmal aufgerufen wird (in einem kleinen Array), dann ist die Geschwindigkeit wesentlich schlechter als "np.bincount". Wenn auf der anderen Seite, wenn Sie die Funktion mehrere Male aufrufen, oder mit einem Array groß genug, dass numba es * on the fly * optimieren kann, sollte numba gut funktionieren. –
Es sollte für Millionen oder Zehnen oder Millionen von Mal pro Sitzung ausgeführt werden und wird über mehrere Prozessoren ausgeführt. Aber wissen Sie zufällig, ob das Starten eines neuen Prozesses eine neue Kompilierung auslöst? – DNF