2016-05-16 27 views
2

In Python sind wie würde ich dies tun:Überprüfen Sie, ob Array-Elemente gleich

sagen, ich habe:

a = [[1, 5], [2,6], [3,3], [4,2]] 
b= [[3, 1], [4,2], [1,8], [2,4]] 

Jetzt möchte ich eine Operation mit den zweiten Spaltenwerte tun, wenn die erste Spalte Werte stimmen überein.

E.G.

a hat einen Eintrag [, 5], durch b gehe jetzt zu sehen, oh es einen Wert [, 8] hat, jetzt will ich 5/8 teilen und diesen Wert in etwa Array speichern c. Als nächstes würde [, 6] und [, 4] übereinstimmen und der nächste Wert in c: 6/4 erhalten werden.

so:

c = [5/8, 6/4, 3/1, 2/2] 

das obige Beispiel. Ich hoffe das macht Sinn. Möchte das mit Numpy und Python.

+2

Ist die erste Spalte von 'a' immer sortiert? Wird in "a" jede Nummer der ersten Spalte in "b" angezeigt? Sind sie von gleicher Größe? – kennytm

+0

@kennytm ja für alle. – Scientized

+0

Sind Duplikate an der ersten Position in jeder Liste zulässig? –

Antwort

4

können Sie np.searchsorted verwenden, um die Positionen zu bekommen, wo b erste Spalte Elemente s erste Spalte Elemente der a entsprechen ", und dass die jeweiligen zweiten Säulenelemente für die Division erhalten mit und schließlich c bekommen. So a und b vorausgesetzt NumPy Arrays zu sein, würde die vektorisiert Implementierung sein -

a0 = a[:,0] 
c = np.true_divide(a[:,1],b[np.searchsorted(a0,b[:,0],sorter=a0.argsort()),1]) 

Der Ansatz der oben aufgeführt arbeitet für einen allgemeinen Fall, wenn die ersten Spaltenelemente von a sind nicht notwendigerweise sortiert. Aber, wenn sie genau wie für die aufgeführte Probe Fall sortiert sind, können Sie einfach ignorieren die sorter Argument Eingang und eine vereinfachte Lösung, wie so -

c = np.true_divide(a[:,1],b[np.searchsorted(a0,b[:,0]),1]) 

Probelauf -

In [35]: a 
Out[35]: 
array([[1, 5], 
     [2, 6], 
     [3, 3], 
     [4, 2]]) 

In [36]: b 
Out[36]: 
array([[3, 1], 
     [4, 2], 
     [1, 8], 
     [2, 4]]) 

In [37]: a0 = a[:,0] 

In [38]: np.true_divide(a[:,1],b[np.searchsorted(a0,b[:,0],sorter=a0.argsort()),1]) 
Out[38]: array([ 0.625, 1.5 , 3. , 1. ]) 
1

Sie können verwenden, um eine einfache Art und Weise O(n^2) mit verschachtelten Schleifen:

c = [] 

for x in a: 
for y in b: 
    if x[0] == y[0]: 
    c.append(x[1]/y[1]) 
    break 

die obigen nützlich ist, wenn die Listen klein sind. Bei großen Listen sollten Sie einen wörterbuchbasierten Ansatz wählen, bei dem die Komplexität O (n) auf Kosten von zusätzlichem Speicherplatz wäre.

4

alle Annahmen im Kommentarbereich Given, dies funktioniert:

from operator import itemgetter 
from __future__ import division 

a = [[1, 5], [2,6], [3,3], [4,2]] 
b = [[3, 1], [4,2], [1,8], [2,4]] 

result = [x/y for (_, x), (_, y) in zip(a, sorted(b, key=itemgetter(0)))] 

Annahmen: Listen gleiche Längen haben, Elemente in der ersten Position für jede Liste eindeutig sind, wird zuerst Liste erstes Element sortiert Jedes Element, das an der ersten Position in a auftritt, tritt auch an der ersten Position in b auf.

+1

geht das davon aus, dass jeder erste Spalteneintrag in a einen entsprechenden Eintrag in b hat? – trans1st0r

+0

Möglicherweise brauchen Sie eine "von __future__ Import Division" – Eric

+0

@ trans1st0r: Ja, weil das ist einer der "Annahmen in der Kommentar-Abschnitt" _ – Eric

0

Ich schlage vor, dass Sie die falsche Datenstruktur verwenden. Beachten Sie, dass Sie, wenn Sie eine Arrayspalte mit eindeutigen Werten zwischen 1 und N (eine Indexspalte) haben, dieselben Daten einfach durch Neuordnung der anderen Spalten codieren könnten. Sobald Sie Ihre Daten neu geordnet haben, können Sie nicht nur die Spalte "Index" löschen, sondern es wird auch einfacher, mit den verbleibenden Daten zu arbeiten.Lassen Sie mich zeigen:

import numpy as np 

N = 5 
a = np.array([[1, 5], [2,6], [3,3], [4,2]]) 
b = np.array([[3, 1], [4,2], [1,8], [2,4]]) 

a_trans = np.ones(N) 
a_trans[a[:, 0]] = a[:, 1] 

b_trans = np.ones(N) 
b_trans[b[:, 0]] = b[:, 1] 

c = a_trans/b_trans 
print c 

Je nach Art des Problems, Sie manchmal einen impliziten Index von Anfang an verwenden können, aber manchmal eine explizite Index kann sehr nützlich sein. Wenn Sie einen expliziten Index benötigen, sollten Sie etwas wie pandas.DataFrame mit besserer Unterstützung für Indexoperationen verwenden.

Verwandte Themen