Frage

Ich fange gerade mit NumPy so kann ich einige Kernkonzepte fehlt ...

Was ist der beste Weg, um eine NumPy Array aus einem Wörterbuch, der Wert Listen?

erstellen

So etwas wie folgt aus:

d = { 1: [10,20,30] , 2: [50,60], 3: [100,200,300,400,500] }

Sollte verwandeln sich in so etwas wie:

data = [
  [10,20,30,?,?],
  [50,60,?,?,?],
  [100,200,300,400,500]
]

Ich werde einige grundlegenden Statistiken über jede Zeile tun, zum Beispiel:

deviations = numpy.std(data, axis=1)

Fragen:

  • Was ist der beste / effizienteste Weg, um die numpy.array aus dem Wörterbuch zu erstellen? Das Wörterbuch ist groß; ein paar Millionen Tasten, die jeweils mit ~ 20 Elementen.

  • Die Anzahl der Werte für jede ‚Reihe‘ ist unterschiedlich. Wenn ich das richtig verstanden, will numpy einheitliche Größe, also was ich dazu einfach die Teile fehlen, um std () glücklich?

Update: - (. ZB Schleifen über ein paar Millionen Artikel ist schnell) Eine Sache, die ich vergaß zu erwähnen, während die Python-Techniken angemessen sind, ist es zu einer einzigen CPU eingeschränkt. Numpy Operationen skaliert gut auf die Hardware und schlug alle CPUs, also sind sie attraktiv.

War es hilfreich?

Lösung

Sie müssen nicht numpy Arrays erstellen rufen numpy.std (). Sie können numpy.std () in einer Schleife über alle Werte Ihres Wörterbuch aufrufen. Die Liste wird auf einen numpy Array on the fly umgewandelt werden, um die Standardabweichung zu berechnen.

Der Nachteil dieser Methode ist, dass die Hauptschleife in Python sein wird und nicht in C. Aber ich denke, das sollte schnell genug sein: Sie werden noch std bei C Geschwindigkeit berechnen, und Sie werden viele Speicher wie Sie sparen nicht 0 Werte speichern, wo Sie variable Größe Arrays haben.

  • Wenn Sie diese weiter optimieren möchten, können Sie Ihre Werte in eine Liste von numpy Arrays gespeichert werden, so dass Sie die Python-Liste tun -> nur numpy Array Umwandlung einmal.
  • , wenn Sie feststellen, dass dies immer noch zu langsam ist, versuchen psycho zu verwenden, um die Python-Schleife zu optimieren.
  • wenn dies immer noch zu langsam ist, versuchen Sie es mit Cython zusammen mit dem numpy Modul. Dieses Tutorial beeindruckende Verbesserungen in der Geschwindigkeit für die Bildverarbeitung in Anspruch nimmt. Oder einfach programmieren, um die ganze std Funktion in Cython (siehe diese für Benchmarks und Beispiele mit Summenfunktion)
  • Eine Alternative zu Cython wäre SWIG mit numpy.i .
  • wenn Sie numpy verwenden wollen, und alles auf C-Ebene berechnet haben, versuchen Sie alle Datensätze von derselben Größe Gruppierung zusammen in verschiedenen Arrays und rufen numpy.std () auf jedem von ihnen. Es sollte wie das folgende Beispiel aussehen.

Beispiel mit O (N) Komplexität:

import numpy
list_size_1 = []
list_size_2 = []
for row in data.itervalues():
    if len(row) == 1:
      list_size_1.append(row)
    elif len(row) == 2:
      list_size_2.append(row)
list_size_1 = numpy.array(list_size_1)
list_size_2 = numpy.array(list_size_2)
std_1 = numpy.std(list_size_1, axis = 1)
std_2 = numpy.std(list_size_2, axis = 1)

Andere Tipps

Es gibt zwar bereits einige ziemlich vernünftige Ideen vorhanden hier, glaube ich folgende ist erwähnenswert.

Füllen mit jedem Standardwert fehlende Daten würden die statistischen Eigenschaften verderben (std, etc). Offensichtlich ist das, warum Mapad netten Trick mit Gruppierung gleich große Datensatz vorgeschlagen. Das Problem bei der es (vorausgesetzt, es gibt keine a-priori-Daten auf Datensätze Längen sind bei der Hand) ist, dass es noch mehr Berechnungen als die einfachste Lösung beinhaltet:

  1. mindestens O (N * log N) 'len' Anrufe und Vergleiche für mit einer effektiven Algorithmus Sortierung
  2. O (N) prüft auf die zweite Art und Weise durch die Liste Gruppen (dessen Anfang und Ende Indizes für die ‚vertikale‘ Achse)
  3. zu erhalten

Psyco ist eine gute Idee (es ist auffallend einfach zu bedienen, so sicher sein, es zu versuchen).

Es scheint, dass der optimale Weg ist, um die Strategie von Mapad in Kugel # 1, aber mit einer Modifikation beschrieben aufzunehmen - nicht die ganze Liste zu erzeugen, sondern durch das Wörterbuch iterieren jede Zeile in numpy.array Umwandlung und Durchführung erforderliche Berechnungen . Wie folgt aus:

for row in data.itervalues():
    np_row = numpy.array(row)    
    this_row_std = numpy.std(np_row)
    # compute any other statistic descriptors needed and then save to some list

Auf jeden Fall ein paar Millionen Schleifen in Python wird nicht so lange dauern, wie man erwarten könnte. Daneben wie eine Routine Berechnung sieht nicht aus, so wen kümmert das, wenn es zusätzliche Sekunde / Minute dauert, wenn es ab und zu laufen oder sogar nur einmal.


Eine verallgemeinerte Variante dessen, was von Mapad vorgeschlagen wurde:

from numpy import array, mean, std

def get_statistical_descriptors(a):
    if ax = len(shape(a))-1
    functions = [mean, std]
    return f(a, axis = ax) for f in functions


def process_long_list_stats(data):
    import numpy

    groups = {}

    for key, row in data.iteritems():
        size = len(row)
        try:
            groups[size].append(key)
        except KeyError:
            groups[size] = ([key])

    results = []

    for gr_keys in groups.itervalues():             
        gr_rows = numpy.array([data[k] for k in gr_keys])       
        stats = get_statistical_descriptors(gr_rows)                
        results.extend( zip(gr_keys, zip(*stats)) )

    return dict(results)

numpy Wörterbuch

Sie können eine strukturierte Anordnung verwenden, um die Fähigkeit zu erhalten, ein numpy Objekt durch einen Schlüssel zu adressieren, wie ein Wörterbuch.

import numpy as np


dd = {'a':1,'b':2,'c':3}
dtype = eval('[' + ','.join(["('%s', float)" % key for key in dd.keys()]) + ']')
values = [tuple(dd.values())]
numpy_dict = np.array(values, dtype=dtype)

numpy_dict['c']

wird jetzt Ausgabe

array([ 3.])
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top