2016-12-20 6 views
2

Ich versuche, die Teilmenge x des gegebenen NumPy Array aList solche zu bekommen, dass das erste Element jeder Zeile sein muß, in der Liste r.gemäß dem ersten Element jeder Zeile

>>> import numpy 
>>> alist = numpy.array([(0, 2), (0, 4), (1, 3), (1, 4), (2, 1), (3, 1), (3, 2), (4, 1), (4, 3), (4, 2)]) 
>>> alist 
array([[0, 2], 
    [0, 4], 
    [1, 3], 
    [1, 4], 
    [2, 1], 
    [3, 1], 
    [3, 2], 
    [4, 1], 
    [4, 3], 
    [4, 2]]) 
>>> r = [1,3] 
>>> x = alist[where first element of each row is in r] #this i need to figure out. 
>>> x 
array([[1, 3], 
    [1, 4], 
    [3, 1], 
    [3, 2]]) 

eine einfache Möglichkeit (ohne Looping, wie ich eine große Datenmenge haben) dies in Python zu tun?

+0

Ich verstehe nicht, warum Sie nicht loopen möchten? Wenn Sie das erste Mal finden, können Sie die Schleife unterbrechen, aber ich sehe keinen anderen Weg als das erste Element zu überprüfen, das zweite und so weiter, bis Sie es gefunden haben oder keine Daten mehr vorhanden sind. – Lex

+1

@Lex native Python-Schleifen sind viel langsamer als gebaut - in numpy Methoden, die normalerweise kompilierten Code unter der Haube verwenden. –

+2

Wenn Ihre Frage beantwortet wurde, können Sie eine der Lösungen akzeptieren. Lesen Sie mehr darüber hier - http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – Divakar

Antwort

2

Scheibe die erste Spalte aus Eingangsanordnung (im Grunde ersten Elem aus jeder Zeile auswählt), dann mit np.in1d mit r als die zweite Eingabe eine Maske eines solchen gültigen Zeilen und schließlich Index in die Reihen der Anordnung mit der Maske zu erzeugen, um die gültigen auszuwählen.

Somit würde die Umsetzung wie so sein -

alist[np.in1d(alist[:,0],r)] 

Probelauf -

In [258]: alist # Input array 
Out[258]: 
array([[0, 2], 
     [0, 4], 
     [1, 3], 
     [1, 4], 
     [2, 1], 
     [3, 1], 
     [3, 2], 
     [4, 1], 
     [4, 3], 
     [4, 2]]) 

In [259]: r # Input list to be searched for 
Out[259]: [1, 3] 

In [260]: np.in1d(alist[:,0],r) # Mask of valid rows 
Out[260]: array([False, False, True, True, False, True, True, 
         False, False, False], dtype=bool) 

In [261]: alist[np.in1d(alist[:,0],r)] # Index and select for final o/p 
Out[261]: 
array([[1, 3], 
     [1, 4], 
     [3, 1], 
     [3, 2]]) 
+0

Dies ist perfekt! Vielen Dank :) – xlax

2

Sie können den Index-Array für die gültigen Zeilen konstruieren einige Indizierung Tricks: Wir können eine zusätzliche hinzufügen Dimension und überprüfen Sie die Gleichheit mit jedem Element Ihrer ersten Spalte:

import numpy as np 
alist = np.array([(0, 2), (0, 4), (1, 3), (1, 4), (2, 1), 
        (3, 1), (3, 2), (4, 1), (4, 3), (4, 2)]) 

inds = (alist[:,0][:,None] == r).any(axis=-1) 
x = alist[inds,:] # the valid rows 

Der Trick ist, dass wir die erste Spalte von alist nehmen, es zu einem (N,1) -förmigen Array machen, Array-Broadcasting im Vergleich zu einem (N,2) -shape Booleschen Array verwenden, und wenn einer der Werte in einer gegebenen Zeile True ist, Wir behalten diesen Index. Das resultierende Index-Array ist das gleiche wie das np.in1d eins in Divakar's answer.

+2

Eine kürzere Form: 'alist [:, 0, None] == r'. – Divakar

+0

@Divakar natürlich! \ * facepalm \ * Danke, bearbeitet :) –

Verwandte Themen