2010-05-05 9 views
6

Supposons que j'ai deux tableaux numpy de la formefusion tableau indexé en Python

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

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

est-il un moyen efficace de les fusionner de telle sorte que je

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

je peux mettre en œuvre une fonction simple en utilisant la recherche pour trouver l'index mais ce n'est pas élégant et potentiellement inefficace pour beaucoup de tableaux et de grandes dimensions. Tout pointeur est apprécié.

Répondre

8

Voir numpy.lib.recfunctions.join_by

Il ne fonctionne que sur des réseaux structurés ou recarrays, donc il y a quelques petits défauts.

D'abord, vous devez être au moins un peu familier avec les tableaux structurés. Voir here si vous n'êtes pas.

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 

Ce sorties:

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

Hope qui aide!

Édition1: Exemple ajouté Édition2: ne devrait pas vraiment se joindre à des flottants ... Champ 'clé' modifié en int.

+1

Merci pour cette réponse perspicace. Pour ma stupidité, existe-t-il un moyen simple de convertir le tableau de structure en ndarray? Merci. – leon

+0

@leon - Voici une façon (en utilisant le tableau "join" dans l'exemple ...): join.view (np.float) .reshape ((join.size, 3)) Espérons que ça aide! –

+1

cela ne fonctionne pas réellement parce que la première colonne est castée en int. C'est pourquoi je demandais. – leon

Questions connexes