2013-07-16 11 views
6

ho due set di dati in serie:Combinare due dati di matrice utilizzando interna join

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

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

voglio combinarle in un unico array come questo:

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

Voglio dire, solo combinare questi linee con la stessa colonna date.

=== === EDIT

Grazie a tutti, Solo per chiarezza, non ho bisogno di quelle linee che non si vedono in entrambe matrice, basta farli cadere.

+1

Pensato all'utilizzo di un dict? – roippi

+2

btw, quelli sono elenchi, non matrici. – geoffspear

+0

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

risposta

5

Organizza i tuoi dati in modo diverso (si può facilmente convertire ciò che già avete a due dict s):

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

Poi:

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

Ciò mancherà quelle voci con le date che non si verificano in entrambi i set. –

+0

@ Jan-Philip Gehrcke: "* Voglio dire, combina quelle linee con la stessa colonna di date. *" – jason

+0

Jason, sì, dice che vuole che vengano combinati, ma non dice che vuole mancare l'altro punti di dati. Lui (o lei) ha bisogno di chiarire. –

0

A meno che entrambi sono molto grandi liste, userei un dizionario:

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 

In caso contrario, sarebbe più efficace per ordinare ciascuno, e poi fare un merge in questo modo. Ma immagino che per la maggior parte degli scopi questo sia abbastanza veloce.

1

Un unico approccio dizionario:

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) 

Questo sarebbe l'equivalente di un join esterno completo (restituisce dati da entrambi i lati anche se da un lato è nullo). Se si voleva un inner join, si potrebbe cambiare a questo:

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

è possibile convertire gli array ad un dizionario, e viceversa.

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

Hai provato? Per me, questo non è l'output atteso: '>>> risultato [['2011-10-10', 3, 4], ['2007-08-09', 5, 3], ['2007-09 -05 ', 1, 1]] ' –

+0

@ Jan-PhilipGehrcke Gehrcke Dovrebbe funzionare ora. – jh314

1

Generator approccio funzione, saltando corrispondente elementi le cui date non corrispondono:

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]] 

Ma sì, se possibile, organizzare i dati in modo diverso.

+0

'zip' (o' izip') ha senso solo se le due liste corrispondono direttamente. Se non lo fanno, potresti non trovare nessuna corrispondenza. – Blckknght

+0

@Blckknght: Sì, hai ragione. – Rao

2

Può essere opportuno menzionare i tipi di dati impostati. come i loro metodi si allineano al tipo di problema. Gli operatori di set consentono di unire gli insiemi in modo semplice e flessibile con giunzioni complete, interne, esterne, sinistra, destra. Come con i dizionari, i set non mantengono l'ordine, ma se si esegue il cast di un set in un elenco, è possibile applicare un ordine sul join risultato. In alternativa, è possibile utilizzare o rdered dictionary.

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

Questo si ottiene solo l'unione delle date nelle liste originali, al fine di ricostruire arr3 si avrebbe bisogno di aggiungere il [1:] dati in arr1 e arr2 dove sono le date nel set di risultati. Questa ricostruzione non sarebbe così accurata come usare le soluzioni del dizionario di cui sopra, ma l'uso di insiemi è degno di considerazione per problemi simili.