Python: Bedingte Elemente im Array

Eine Frage von einem kompletten Python-Anfänger.

Ich habe ein Spalten-Array, wo ich zwingen müssen, bestimmte Werte auf Null zu setzen, abhängig von einer bedingten Anweisung, die auf ein anderes Array angewendet wird. Ich habe zwei Lösungen gefunden, die beide die richtige Antwort geben. Aber sie sind beide ziemlich zeitaufwendig für die größeren Arrays, die ich normalerweise benötige (> 1E6 Elemente) – auch ich vermute, dass es schlechte Programmierungstechnik ist. Die beiden Versionen sind:

  • Python Write to Text File Dictionary Zeigt falsche Informationen an
  • Python: Reduzierung der Speicherauslastung des Wörterbuchs
  • Das Ergebnis von Minhash speichern
  • Wie man zwei verschachtelte Wörterbücher unter einem selben Wörterbuch zusammenführt
  • Zählen Sie eindeutige Werte pro eindeutige Schlüssel im Python-Wörterbuch
  • Wie man durch Wörterbuch in einem Wörterbuch in django Vorlage iterieren?
  • from numpy import zeros,abs,multiply,array,reshape def testA(y, f, FC1, FC2): c = zeros((len(f),1)) for n in xrange(len(f)): if abs(f[n,0]) >= FC1 and abs(f[n,0]) <= FC2: c[n,0] = 1. w = multiply(c,y) return w def testB(y, f, FC1, FC2): z = [(abs(f[n,0])>=FC1 and abs(f[n,0])<=FC2) for n in xrange(len(f))] z = multiply(array(z,dtype=float).reshape(len(f),1), y) return z 

    Die Eingangs-Arrays sind Spalten-Arrays, da dies mit der Nachverarbeitung übereinstimmt. Der Test kann wie folgt durchgeführt werden:

     >>> from numpy.random import normal as randn >>> fs, N = 1.E3, 2**22 >>> f = fs/N*arange(N).reshape((N,1)) >>> x = randn(size=(N,1)) >>> w1 = testA(x,f,200.,550.) >>> z1 = testB(x,f,200.,550.) 

    Auf meinem Laptop testA dauert 18,7 Sekunden und testB nimmt 19.3 – beide für N = 2 ** 22. In testB habe ich auch versucht, "z = [None] * len (f)" zuzuordnen, wie in einem anderen Thread vorgeschlagen, aber das macht keinen Unterschied.

    Ich habe zwei Fragen, die ich hoffe, die gleiche Antwort zu haben:

    1. Was ist die "richtige" Python-Lösung für dieses Problem?
    2. Gibt es etwas, was ich tun kann, um die Antwort schneller zu bekommen?

    Ich habe absichtlich keine Zeit mit dem kompilierten Python zum Beispiel verwendet – ich wollte mal einen Arbeitscode haben. Hoffentlich auch etwas, was gut ist Python-Stil. Ich hoffe, in der Lage zu sein, die Ausführungszeit für N = 2 ** 22 unter zwei Sekunden oder so zu bekommen. Diese besondere Operation wird oft verwendet werden, so dass die Ausführungszeit ist wichtig.

    Ich entschuldige mich im Voraus, wenn die Frage dumm ist – ich war nicht in der Lage, eine Antwort in der überwältigenden Menge von nicht immer leicht zugänglichen Python-Dokumentation oder in einem anderen Thread zu finden.

    2 Solutions collect form web for “Python: Bedingte Elemente im Array”

    Bool array verwenden, um auf Elemente in array y zuzugreifen:

     def testC(y, f, FC1, FC2): f2 = abs(f) idx = (f2>=FC1) & (f2<=FC2) y[~idx] = 0 return y 

    Alle diese sind langsamer als die HYRY-Lösung mit einem großen Faktor:

    Wie wäre es mit

    ( x[1] if FC1<=abs(x[0])<=FC2 else 0 for x in itertools.izip(f,x) )

    Wenn Sie zufällig zugreifen müssen (sehr langsam)

    [ x[1] if FC1<=abs(x[0])<=FC2 else 0 for x in itertools.izip(f,x) ]

    Oder du kannst auch die Karte verwenden

    map(lambda x: x[1] if FC1<=abs(x[0])<=FC2 else 0 , itertools,izip(f,x))

    Oder mit vektorisieren (schneller als A und B aber viel viel langsamer als C)

     b1v = np.vectorize(lambda a,b: a if 200<=abs(b)<=550 else 0) b1 = b1v(f,x) 
    Python ist die beste Programmiersprache der Welt.