2010-05-05 13 views
6

Supponiamo che ho due matrici numpy della formafusione array indicizzato in Python

x = [[1,2] 
    [2,4] 
    [3,6] 
    [4,NaN] 
    [5,10]] 

y = [[0,-5] 
    [1,0] 
    [2,5] 
    [5,20] 
    [6,25]] 

c'è un modo efficiente per unirle tale che ho

xmy = [[0, NaN, -5 ] 
     [1, 2, 0 ] 
     [2, 4, 5 ] 
     [3, 6, NaN] 
     [4, NaN, NaN] 
     [5, 10, 20 ] 
     [6, NaN, 25 ] 

posso implementare una funzione semplice usando la ricerca per trovare l'indice ma questo non è elegante e potenzialmente inefficiente per molti array e grandi dimensioni. Qualsiasi puntatore è apprezzato.

risposta

8

Vedi numpy.lib.recfunctions.join_by

Funziona solo su array strutturati o recarrays, quindi ci sono un paio di pieghe.

Per prima cosa è necessario avere una certa familiarità con gli array strutturati. Vedi here se non lo sei.

import numpy as np 
import numpy.lib.recfunctions 

# Define the starting arrays as structured arrays with two fields ('key' and 'field') 
dtype = [('key', np.int), ('field', np.float)] 
x = np.array([(1, 2), 
      (2, 4), 
      (3, 6), 
      (4, np.NaN), 
      (5, 10)], 
      dtype=dtype) 

y = np.array([(0, -5), 
      (1, 0), 
      (2, 5), 
      (5, 20), 
      (6, 25)], 
      dtype=dtype) 

# You want an outer join, rather than the default inner join 
# (all values are returned, not just ones with a common key) 
join = np.lib.recfunctions.join_by('key', x, y, jointype='outer') 

# Now we have a structured array with three fields: 'key', 'field1', and 'field2' 
# (since 'field' was in both arrays, it renamed x['field'] to 'field1', and 
# y['field'] to 'field2') 

# This returns a masked array, if you want it filled with 
# NaN's, do the following... 
join.fill_value = np.NaN 
join = join.filled() 

# Just displaying it... Keep in mind that as a structured array, 
# it has one dimension, where each row contains the 3 fields 
for row in join: 
    print row 

Questo uscite:

(0, nan, -5.0) 
(1, 2.0, 0.0) 
(2, 4.0, 5.0) 
(3, 6.0, nan) 
(4, nan, nan) 
(5, 10.0, 20.0) 
(6, nan, 25.0) 

Speranza che aiuta!

Edit1: Aggiunto esempio Edit2: Realmente non si deve unire ai float ... Modificato il campo 'chiave' su un int.

+1

Grazie per questa risposta perspicace. Per la mia stupidità, c'è un modo semplice per convertire l'array di strutture in ndarray? Grazie. – leon

+0

@leon - Ecco un modo (usando la matrice "join" nell'esempio ...): join.view (np.float) .reshape ((join.size, 3)) Spero che ti aiuti! –

+1

in realtà non funziona perché la prima colonna è castata come int. Questo è il motivo per cui lo stavo chiedendo. – leon

Problemi correlati