2016-09-13 3 views
0

Ich versuche numpy im Gegensatz zu geschachtelten für Schleifen zu verwenden und versuchen zu finden, wenn ein Wert innerhalb einer bestimmten Toleranz ist.Numpy in1D mehrere Auswertungsanweisungen

Der Code in Python mit den verschachtelten Schleifen funktioniert gut und ich bekomme die Ergebnisse, die ich suche, aber leider ist nicht skalierbar und dauert ein paar Stunden, wenn die Größe der Liste 200k plus Elemente ist.

Was habe ich jetzt als zweite Iteration des Prozesses ist:

import numpy as np 
import numpy.ma as ma 
from numpy import newaxis 

#some data provided as an example 
a= np.array([['id1', 8988, 7997, 210.0, 240.0, 180, 300, 7000.0, 9038, 8938, 8047, 7947, 231.0, 189.0, 8400.0, 5600.0], 
['id2', 7314, 5613, 210.0, 240.0, 180, 300, 7000.0, 7364, 7264, 5663, 5563, 231.0, 189.0, 8400.0, 5600.0], 
['id3', 5520, 9888, 35.0, 55.0, -125, 235, 7000.0, 5570, 5470, 9938, 9838, 38.5, 31.5, 8400.0, 5600.0], 
['id4', 6270, 4270, 0.0, 90.0, -90, 270, 7000.0, 6320, 6220, 4320, 4220, 0.0, 0.0, 8400.0, 5600.0]]) 

print(a) 

validation = np.ma.MaskedArray(((a[:, 1:2] <= a[:, 8:9]) & (a[:, 1:2] >= a[:, 9:10])) \ 
    & ((a[:, 2:3] <= a[:, 10:11]) & (a[:, 2:3] >= a[:, 11:12])) \ 
    & ((a[:, 3:4] <= a[:, 12:13]) & (a[:, 3:4] >= a[:, 13:14])) \ 
    & ((a[:, 7:8] <= a[:, 14:15]) & (a[:, 7:8] >= a[:, 15:]))) 

e = np.in1d(a[:, 1:2], a[validation]) <-- this is were I try to apply the check for tolerances 
e1 = np.where(e[:, newaxis], a[:, :1], np.zeros(1, dtype=int)) 
ef = e1[~np.all(e1 == 0, axis=0)] 

print('Final array', ef) 

Beim ersten Versuch numpy des meshgrid mit allen Kombinationen zu erstellen, eine für jeden Vergleich, und dann eine numpy.where auf das tun Ergebnisse funktioniert es, aber wenn 100k plus Elemente verwenden, ist die erforderliche Gesamtmenge an RAM mehr als 150 GB RAM.

Jede Hilfe, Beratung, Kommentar ist willkommen.

+0

Warum' maskiert array' verwenden? Beginnen Sie mit diesem logischen Ausdruck. Das sollte ein Array von Form '(n, 1)' und dtype boolean sein. Eine andere Sache, überspringen Sie den Versuch, mit einem 2D-Array zu arbeiten.'np.in1d' Wörter in' 1d'. – hpaulj

Antwort

0

Wenn ich kopiere-n-Paste Ihre a ich ein 4x16 Array von Strings

In [37]: a 
Out[37]: 
array([['id1', '8988', '7997', '210.0', '240.0', '180', '300', '7000.0', 
     '9038', '8938', '8047', '7947', '231.0', '189.0', '8400.0', 
     '5600.0'], 
     .... 
     dtype='<U6') 

Anwenden der validation Ausdruck erhalten, dass produziert (vergessen Sie das Maskedarray Bit). Natürlich versucht es einen String-Vergleich.

array([[ True], 
     [ True], 
     [ True], 
     [ True]], dtype=bool) 

Wenn ich entfernen Sie die id Spalte Ich erhalte eine 4x15 von Schwimmern

In [39]: a 
Out[39]: 
array([[ 8988. , 7997. , 210. , 240. , 180. , 300. , 7000. , 
     9038. , 8938. , 8047. , 7947. , 231. , 189. , 8400. , 
     5600. ], 
...]]) 

mit, dass ich denke, die validation Test vereinfacht werden kann:

In [41]: ((a[:, 0] <= a[:, 7]) & (a[:, 0] >= a[:, 8])) \ 
    ...:  & ((a[:, 1] <= a[:, 9]) & (a[:, 1] >= a[:, 10])) \ 
    ...:  & ((a[:, 2] <= a[:, 11]) & (a[:, 2] >= a[:, 12])) \ 
    ...:  & ((a[:, 6] <= a[:, 13]) & (a[:, 6] >= a[:, 14])) 
Out[41]: array([ True, True, True, True], dtype=bool) 

Was tut das?

e = np.in1d(a[:, 1:2], a[validation]) 

a[validation] ist die alle ok Reihen von a; a[:,0] ist der erste Wert jeder Zeile. Aber np.in1d soll den Inhalt eines 1d-Arrays gegen den Inhalt eines anderen 1d überprüfen. Wie Sie es geschrieben haben, verwendet es 2 2d-Arrays.

An diesem Punkt werde ich aufgeben.

Konstruieren Sie einen einfacheren Testfall und stellen Sie sicher, dass er bei jedem Schritt funktioniert. Zeigen Sie die Zwischenwerte an. Dann können wir die Schritte besprechen, in denen es nicht funktioniert.

0

Wie hpaulj sagt, zuerst loswerden die id 's.

Zweitens, warum sind Ihre Toleranzen und Ihre Werte im selben Array? Wenn Sie min_tol und max_tol in separaten Arrays hatten, könnten Sie dies viel einfacher tun.

Sie müssen wahrscheinlich so etwas wie (nach der id ‚entfernen e):

min_tol = a[:, 8:15:2] 
max_tol = a[:, 7:14:2] 
a_val = np.c_[a[:, :3], a[:, 6]] 
validation = (a_val >= min_tol) & (a_val <= max_tol) 

Obwohl ich in diesem Stadium nicht wirklich sicher bin ...

Verwandte Themen