2016-08-01 15 views
2

Ich schreibe Code, der Numba verwendet, um JIT meinen Python-Code zu kompilieren. Die Funktion nimmt zwei Arrays gleicher Länge als Eingabe auf, wählt zufällig einen Slicing-Punkt und gibt ein Tupel mit zwei Frankenstein-Arrays zurück, die aus Teilen der beiden Eingabe-Strings bestehen. Numba unterstützt jedoch noch nicht die Funktion numpy.concatenate (weiß nicht, ob es jemals funktioniert). Da ich Numpy nicht fallen lassen möchte, weiß jemand eine performante Lösung für die Verkettung zweier Numpy-Arrays ohne die Verkettungsfunktion?Wie zwei numpy ndarrays verketten ohne verketten

def randomSlice(str1, str2): 
    lenstr = len(str1) 
    rnd = np.random.randint(1, lenstr) 
    return (np.concatenate((str1[:rnd], str2[rnd:])), np.concatenate((str2[:rnd], str1[rnd:]))) 

Antwort

1

Dies könnte für Sie arbeiten:

import numpy as np 
import numba as nb 

@nb.jit(nopython=True) 
def randomSlice_nb(str1, str2): 
    lenstr = len(str1) 
    rnd = np.random.randint(1, lenstr) 

    out1 = np.empty_like(str1) 
    out2 = np.empty_like(str1) 

    out1[:rnd] = str1[:rnd] 
    out1[rnd:] = str2[rnd:] 

    out2[:rnd] = str2[:rnd] 
    out2[rnd:] = str1[rnd:] 
    return (out1, out2) 

Auf meinem Rechner mit Numba 0,27 und Timing über das timeit Modul sicherzustellen, dass ich bin nicht mitgerechnet die jit Zeit in den Statistiken (oder Sie könnte es einmal ausführen, und dann Zeit nachfolgende Aufrufe), die Numba-Version gibt eine kleine, aber nicht zu vernachlässigende Leistungssteigerung auf verschiedenen Größen Eingabearrays von Ints oder Floats. Wenn die Arrays einen D-Typ von etwa |S1 haben, ist numba wesentlich langsamer. Das Numba-Team hat sehr wenig Zeit damit verbracht, nichtnumerische Anwendungsfälle zu optimieren, daher ist dies nicht besonders überraschend. Ich bin ein wenig unklar über die genaue Form Ihrer Eingabe-Arrays str1 und str2, so kann ich nicht genau garantieren, dass der Code für Ihren spezifischen Anwendungsfall funktioniert.

+0

Funktioniert wie ein Charme. Ich wundere mich nur über den Leistungsaufwand, der durch das Ersetzen von Elementen auf out1 und out2 entsteht, aber im Moment ist genau das, was ich brauchte. Vielen Dank. (Für die Aufzeichnung waren die Str-Eingaben einfach nur 1D ndarrays) –

+0

Wenn Sie 'np.empty' oder' np.empty_like' verwenden, ordnen Sie nur Speicher für das Array zu und füllen es nicht, daher sollte es schnell sein. Die meisten numpy Funktionen, die ein neues Array zurückgeben, müssen etwas Ähnliches tun, obwohl sie oft eine niedrigere C-Funktion wie 'PyArray_ConcatenateArrays' benutzen. Selbst dann können Sie sehen, dass die Funktion Speicher zuweist und dann Daten in sie kopiert. – JoshAdel

+0

Der einzige Weg, um dies zu umgehen, ist, wenn Sie Ausgangsarrays im Voraus zuweisen und sie übergeben, was ich gelegentlich tun werde, wenn ich viele kleine Arrays immer und immer wieder erstellen werde. Es macht den Code jedoch hässlicher. – JoshAdel