2010-05-05 9 views
6

Angenommen, ich habe zwei numpy Arrays der Formverschmelzenden indiziertes Array in Python

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

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

ist es eine effiziente Möglichkeit, sie derart zu fusionieren, dass ich

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

I eine einfache Funktion implementieren kann, Verwenden Sie die Suche, um den Index zu finden, aber dies ist nicht elegant und potenziell ineffizient für viele Arrays und große Dimensionen. Jeder Zeiger wird geschätzt.

Antwort

8

Siehe numpy.lib.recfunctions.join_by

Es funktioniert nur auf strukturierte Arrays oder recarrays, so gibt es ein paar Knicke.

Zuerst müssen Sie mit strukturierten Arrays zumindest etwas vertraut sein. Siehe here, wenn Sie nicht sind.

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 

Diese Ausgänge:

(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) 

Hoffnung, das hilft!

Edit1: Hinzugefügt Beispiel Edit2: Wirklich nicht mit Floats Join ... Geändert 'key' Feld zu einem int.

+1

Danke für diese aufschlussreiche Antwort. Für meine Dummheit gibt es eine einfache Möglichkeit, Struktur-Array in NDarray zu konvertieren? Vielen Dank. – leon

+0

@leon - Hier ist eine Art und Weise (mit dem "Join" Array im Beispiel ...): join.view (np.float) .reshape ((join.size, 3)) Hoffnung, das hilft! –

+1

das funktioniert eigentlich nicht, weil die erste Spalte als int gegossen wird. Deshalb habe ich gefragt. – leon

Verwandte Themen