2013-07-16 13 views
6

Mam dwa zestawy danych w tablicy:Łączenie dwóch danych Array za pomocą sprzężenia wewnętrznego

arr1 = [ 
    ['2011-10-10', 1, 1], 
    ['2007-08-09', 5, 3], 
    ... 
] 

arr2 = [ 
    ['2011-10-10', 3, 4], 
    ['2007-09-05', 1, 1], 
    ... 
] 

Chcę połączyć je w jednej tablicy tak:

arr3 = [ 
    ['2011-10-10', 1, 1, 3, 4], 
    ... 
] 

To znaczy, po prostu połączyć te linie o tej samej kolumnie date.

=== EDIT ===

Dzięki wszystkim, tylko dla wyjaśnienia, nie muszę te linie, które nie pojawiają się zarówno w tablicy, po prostu upuść.

+1

Myślisz o używaniu dyktatu? – roippi

+2

btw, to są listy, a nie tablice. – geoffspear

+0

http: //code.activestate.com/recipes/577937-inner-join/ – Delta

Odpowiedz

5

Uporządkuj swoje dane w różny sposób (można łatwo konwersji, co już masz dwa dict s):

d1 = { '2011-10-10': [1, 1], 
     '2007-08-09': [5, 3] 
    } 
d2 = { '2011-10-10': [3, 4], 
     '2007-09-05': [1, 1] 
    } 

Następnie:

d3 = { k : d1[k] + d2[k] for k in d1 if k in d2 } 
+0

Spowoduje to pominięcie tych wpisów z datami, które nie występują w obu zestawach. –

+0

@ Jan-Philip Gehrcke: "To znaczy, po prostu połącz te wiersze z tą samą kolumną z datą." " – jason

+0

Jason, tak, mówi, że chce, żeby były połączone, ale nie mówi, że chce przegapić inne punkty danych. On (lub ona) musi wyjaśnić. –

0

chyba że obie są bardzo duże listy, będę używać słownika:

arr1 = [ 
    ['2011-10-10', 1, 1], 
    ['2007-08-09', 5, 3] 
] 

arr2 = [ 
    ['2011-10-10', 3, 4], 
    ['2007-09-05', 1, 1] 
] 

table_1 = dict((tup[0], tup[1:]) for tup in arr1) 
table_2 = dict((tup[0], tup[1:]) for tup in arr2) 
merged = {} 
for key, value in table_1.items(): 
    other = table_2.get(key) 
    if other: 
     merged[key] = value + other 

przeciwnym razie byłoby bardziej skuteczne, aby rozwiązać każdy, a następnie zrobić scalania tamtędy. Ale wyobrażam sobie, że w większości przypadków będzie to wystarczająco szybkie.

1

jednego podejścia Słownik

tmp = {} 
# add as many as you like into the outermost array. 
for outer in [arr1,arr2]: 
    for inner in outer: 
     start, rest = inner[0], inner[1:] 
     # the list if key exists, else create a new list. Append to the result 
     tmp[start] = tmp.get(start,[]) + rest 

output = [] 

for k,v in tmp.iteritems(): 
    output.append([k] + v) 

Byłoby odpowiednik pełnego sprzężenia zewnętrznego (zwraca dane z obu stron, nawet jeśli jedna strona jest zerowy). Jeśli chcesz dołączyć do połączenia wewnętrznego, możesz zmienić to na:

tmp = {} 
keys_with_dupes = [] 

for outer in [arr1,arr2]: 
    for inner in outer: 
     start, rest = inner[0], inner[1:] 
     original = tmp.get(start,[]) 
     tmp[start] = original + rest 
     if original: 
      keys_with_dupes.append(start) 

output = [] 

for k in keys_with_dupes: 
    v = tmp[k] 
    output.append([k] + v) 
2

Możesz przekonwertować tablice na dyktando iz powrotem.

d1 = dict((x[0],x[1:]) for x in arr1) 
d2 = dict((x[0],x[1:]) for x in arr2) 
keys = set(d1).union(d2) 
n = [] 
result = dict((k, d1.get(k, n) + d2.get(k, n)) for k in keys) 
+0

Czy próbowałeś? Dla mnie to nie jest oczekiwany wynik: '>>> result [['2011-10-10', 3, 4], ['2007-08-09', 5, 3], ['2007-09 -05 ', 1, 1]] ' –

+0

@ Jan-PhilipGehrcke Gehrcke To powinno teraz działać. – jh314

1

podejście funkcja Generator, omijając odpowiadający elementy, których daty nie są zgodne:

import itertools 
def gen(a1, a2): 
    for x,y in itertools.izip(a1, a2): 
     if x[0] == y[0]: 
      ret = list(x) 
      ret.extend(y[1:]) 
      yield ret 
     else: 
      continue 

>>print list(gen(arr1, arr2)) 
[['2011-10-10', 1, 1, 3, 4]] 

Ale tak, jeśli to możliwe, uporządkuj dane inaczej.

+0

'zip' (lub' izip') ma sens tylko wtedy, gdy dwie listy bezpośrednio odpowiadają. Jeśli nie, możesz nie znaleźć żadnego z meczów. – Blckknght

+0

@Blckknght: Tak, masz rację. – Rao

2

Warto wspomnieć o ustawionych typach danych. ponieważ ich metody są dostosowane do rodzaju problemu. Zestaw operatorów pozwala łatwo i elastycznie łączyć zestawy z pełnym, wewnętrznym, zewnętrznym, lewym i prawym złączeniem. Podobnie jak w przypadku słowników, zestawy nie zachowują porządku, ale jeśli rzucisz zestaw z powrotem na listę, możesz zastosować zamówienie w wyniku łączenia. Alternatywnie możesz użyć o rdered dictionary.

set1 = set(x[0] for x in arr1) 
set2 = set(x[0] for x in arr2) 
resultset = (set1 & set2) 

to tylko dostaje unię terminach w oryginalnych list, aby zrekonstruować arr3 trzeba byłoby dołączyć [1:] Dane w arr1 i ARR2 gdzie terminy są w zestawie wyników. Ta rekonstrukcja nie byłaby tak zadbana jak przy użyciu powyższych rozwiązań słownikowych, ale używanie zestawów jest warte rozważenia w przypadku podobnych problemów.

Powiązane problemy