2016-09-28 5 views
2

Unten Teeny/Spielzeug-Versionen viel größer/komplexen Datenrahmen mit Ich arbeite:Auf der default/Abwert für Outer-Joins

>>> A 
    key   u   v   w   x 
0 a 0.757954 0.258917 0.404934 0.303313 
1 b 0.583382 0.504687  NaN 0.618369 
2 c  NaN 0.982785 0.902166  NaN 
3 d 0.898838 0.472143  NaN 0.610887 
4 e 0.966606 0.865310  NaN 0.548699 
5 f  NaN 0.398824 0.668153  NaN 

>>> B 
    key   y   z 
0 a 0.867603  NaN 
1 b  NaN 0.191067 
2 c 0.238616 0.803179 
3 p 0.080446  NaN 
4 q 0.932834  NaN 
5 r 0.706561 0.814467 

(FWIW, am Ende dieses Beitrags, liefere ich Code zu erzeugen, diesen Datenrahmen.)

ich schließt ich diesen Datenrahmen eine äußere produzieren will auf der key Spalte , so dass die von den äußeren induzierten neuen Positionen get Standardwert 0.0 verbinden. IOW, das gewünschte Ergebnis wie dieses

key   u   v   w   x   y   z 
0 a 0.757954 0.258917 0.404934 0.303313 0.867603  NaN 
1 b 0.583382 0.504687  NaN 0.618369  NaN 0.191067 
2 c  NaN 0.982785 0.902166  NaN 0.238616 0.803179 
3 d 0.898838 0.472143  NaN 0.610887 0.000000 0.000000 
4 e 0.966606 0.86531  NaN 0.548699 0.000000 0.000000 
5 f  NaN 0.398824 0.668153  NaN 0.000000 0.000000 
6 p 0.000000 0.000000 0.000000 0.000000 0.080446  NaN 
7 q 0.000000 0.000000 0.000000 0.000000 0.932834  NaN 
8 r 0.000000 0.000000 0.000000 0.000000 0.706561 0.814467 

(Beachten Sie, dass diese gewünschte Ausgabe einige NaNs enthält, nämlich diejenigen, die bereits in A oder B vorhanden waren.) Sieht

Die merge Methode ruft mich Teil Weg dorthin , aber die ausgefüllten in Standardwerte sind NaN ist, nicht 0,0 ist:

>>> C = pandas.DataFrame.merge(A, B, how='outer', on='key') 
>>> C 
    key   u   v   w   x   y   z 
0 a 0.757954 0.258917 0.404934 0.303313 0.867603  NaN 
1 b 0.583382 0.504687  NaN 0.618369  NaN 0.191067 
2 c  NaN 0.982785 0.902166  NaN 0.238616 0.803179 
3 d 0.898838 0.472143  NaN 0.610887  NaN  NaN 
4 e 0.966606 0.865310  NaN 0.548699  NaN  NaN 
5 f  NaN 0.398824 0.668153  NaN  NaN  NaN 
6 p  NaN  NaN  NaN  NaN 0.080446  NaN 
7 q  NaN  NaN  NaN  NaN 0.932834  NaN 
8 r  NaN  NaN  NaN  NaN 0.706561 0.814467 

fillna die Methode, um die gewünschte Ausgabe zu erzeugen, fehl, weil es einige Positionen verändert werden, dass sein sollte lef t unverändert:

>>> C.fillna(0.0) 
    key   u   v   w   x   y   z 
0 a 0.757954 0.258917 0.404934 0.303313 0.867603 0.000000 
1 b 0.583382 0.504687 0.000000 0.618369 0.000000 0.191067 
2 c 0.000000 0.982785 0.902166 0.000000 0.238616 0.803179 
3 d 0.898838 0.472143 0.000000 0.610887 0.000000 0.000000 
4 e 0.966606 0.865310 0.000000 0.548699 0.000000 0.000000 
5 f 0.000000 0.398824 0.668153 0.000000 0.000000 0.000000 
6 p 0.000000 0.000000 0.000000 0.000000 0.080446 0.000000 
7 q 0.000000 0.000000 0.000000 0.000000 0.932834 0.000000 
8 r 0.000000 0.000000 0.000000 0.000000 0.706561 0.814467 

Wie kann ich die gewünschte Ausgabe effizient erreichen? (Performance zählt hier, weil ich beabsichtige, diese Operation auszuführen auf viel größere Datenrahmen als die hier gezeigten.)


FWIW, unten ist der Code das Beispiel zur Erzeugung von Datenrahmen A und B.

from pandas import DataFrame 
from collections import OrderedDict 
from random import random, seed 

def make_dataframe(rows, colnames): 
    return DataFrame(OrderedDict([(n, [row[i] for row in rows]) 
           for i, n in enumerate(colnames)])) 

maybe_nan = lambda: float('nan') if random() < 0.4 else random() 

seed(0) 

A = make_dataframe([['a', maybe_nan(), maybe_nan(), maybe_nan(), maybe_nan()], 
        ['b', maybe_nan(), maybe_nan(), maybe_nan(), maybe_nan()], 
        ['c', maybe_nan(), maybe_nan(), maybe_nan(), maybe_nan()], 
        ['d', maybe_nan(), maybe_nan(), maybe_nan(), maybe_nan()], 
        ['e', maybe_nan(), maybe_nan(), maybe_nan(), maybe_nan()], 
        ['f', maybe_nan(), maybe_nan(), maybe_nan(), maybe_nan()]], 
        ('key', 'u', 'v', 'w', 'x')) 

B = make_dataframe([['a', maybe_nan(), maybe_nan()], 
        ['b', maybe_nan(), maybe_nan()], 
        ['c', maybe_nan(), maybe_nan()], 
        ['p', maybe_nan(), maybe_nan()], 
        ['q', maybe_nan(), maybe_nan()], 
        ['r', maybe_nan(), maybe_nan()]], 
        ('key', 'y', 'z')) 

Für Falle Mehrtasten äußeren Joins here sehen.

Antwort

1

können Sie füllen Nullen nach dem merge:

res = pd.merge(A, B, how="outer") 
res.loc[~res.key.isin(A.key), A.columns] = 0 

EDIT

überspringen key Säule:

res.loc[~res.key.isin(A.key), A.columns.drop("key")] = 0 
+0

Frage: wie würde man diese Lösung auf den Fall verallgemeinern, wo Die Zusammenführung erfolgt in mehreren Spalten, z 'merge (..., on = ('Schlüssel1', 'Schlüssel2', ...), ...)'? – kjo

+0

Ich habe keine Ahnung, Sie können nicht wissen, was die Join-Spalten nach dem Aufruf von 'merge()' sind. – HYRY

+0

Wenn Sie private Operation verwenden, können Sie die Information erhalten: 'mo = pd.tools.merge._MergeOperation (A, B, how =" äußere "); print (mo.left_on) ' – HYRY

Verwandte Themen