2017-06-29 5 views
1

Ich habe die folgende Funktion, die ein numpy Array von Floats und eine ganze Zahl als Argumente nimmt. Jede Zeile im Array "counts" ist das Ergebnis eines Experiments, und ich möchte nach dem Zufallsprinzip eine Liste der Experimente zeichnen und addieren, dann diesen Prozess wiederholen, um viele Probengruppen zu erstellen.Funktion optimieren Slicing numpy Arrays

def my_function(counts,nSamples): 
    ''' Create multiple randomly drawn (with replacement) 
     samples from the raw data ''' 
    nSat,nRegions = counts.shape 
    sampleData = np.zeros((nSamples,nRegions)) 
    for i in range(nSamples): 
     rc = np.random.randint(0,nSat,size=nSat) 
     sampleData[i] = counts[rc].sum(axis=0) 
    return sampleData 

Diese Funktion scheint ziemlich langsam, in der Regel zählt mit rund 100.000 Zeilen (und 4 Spalten) und NSamples ist um das Jahr 2000 habe ich versucht numba und implizit für Schleifen mit diesem Code ohne Erfolg, um zu versuchen und zu beschleunigen. Was gibt es für andere Methoden, um die Geschwindigkeit zu erhöhen?

Ich habe cProfile auf die Funktion ausgeführt und die folgende Ausgabe erhalten.

8005 Funktionsaufrufe in 60,208 Sekunden

Sortiert nach: Standard Name

ncalls tottime percall cumtime percall filename:lineno(function) 

    1 0.000 0.000 60.208 60.208 <string>:1(<module>) 

2000 0.010 0.000 13.306 0.007 _methods.py:31(_sum) 

    1 40.950 40.950 60.208 60.208 optimize_bootstrap.py:25(bootstrap) 

    1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 

2000 5.938 0.003 5.938 0.003 {method 'randint' of 'mtrand.RandomState' objects} 

2000 13.296 0.007 13.296 0.007 {method 'reduce' of 'numpy.ufunc' objects} 

2000 0.015 0.000 13.321 0.007 {method 'sum' of 'numpy.ndarray' objects} 

    1 0.000 0.000 0.000 0.000 {numpy.core.multiarray.zeros} 

    1 0.000 0.000 0.000 0.000 {range} 

Antwort

0

Sind Sie sicher, dass

rc = np.random.randint(0,nSat,size=nSat)

ist, was Sie wollen, statt size=someconstant? Ansonsten summieren Sie alle Zeilen mit vielen Wiederholungen.


bearbeiten hilft es das Aufschneiden insgesamt mit einem Matrixprodukt zu ersetzen:

rcvec=np.zeros(nSat,np.int) for i in rc: rcvec[i]+=1 sampleData[i] = rcvec.dot(counts)

(vielleicht gibt es eine Funktion in numpy, die Sie rcvec schneller geben kann)

+0

Ja, ich bin – Jack

+0

eine Bootstrap-Analyse zu tun wie ich sehe. Hilft das oben genannte? –

0

Generieren Sie einfach alle Indizes auf einmal mit einer 2D Größe für np.random.randint, verwenden Sie diese, um inzu indizierenArray und summiere dann entlang der ersten Achse, genau wie du es mit dem Loopy gemacht hast.

So ein vektorisiert Weg und als solche schneller ein, würde wie so sein -

RC = np.random.randint(0,nSat,size=(nSat, nSamples)) 
sampleData_out = counts[RC].sum(axis=0)