2015-01-27 17 views
14

Ich habe 2 Datenrahmen, von denen einer zusätzliche Informationen für einige (aber nicht alle) der Zeilen in den anderen hat.Pandas Merge Datenrahmen füllen fehlende Werte

names = df({'names':['bob','frank','james','tim','ricardo','mike','mark','joan','joe'], 
      'position':['dev','dev','dev','sys','sys','sys','sup','sup','sup']}) 
info = df({'names':['joe','mark','tim','frank'], 
      'classification':['thief','thief','good','thief']}) 

Ich mag die Klassifizierung Spalt aus dem info Datenrahmen nehmen oben und fügen Sie es den names Datenrahmen oben. Wenn ich jedoch combined = pd.merge(names, info) mache, ist der resultierende Datenrahmen nur 4 Zeilen lang. Alle Zeilen, die keine zusätzlichen Informationen enthalten, werden gelöscht.

Idealerweise hätte ich die Werte in diesen fehlenden Spalten auf unbekannt gesetzt. Daraus ergibt sich ein Datenrahmen, in dem einige Leute die Theives sind, einige sind gut und der Rest ist unbekannt.

EDIT: Eine der ersten Antworten, die ich erhielt, schlug vor, mit Merge Outter, die einige seltsame Dinge zu tun scheint. Hier ist ein Codebeispiel:

names = df({'names':['bob','frank','bob','bob','bob''james','tim','ricardo','mike','mark','joan','joe'], 
      'position':['dev','dev','dev','dev','dev','dev''sys','sys','sys','sup','sup','sup']}) 
info = df({'names':['joe','mark','tim','frank','joe','bill'], 
      'classification':['thief','thief','good','thief','good','thief']}) 
what = pd.merge(names, info, how="outer") 
what.fillna("unknown") 

Das Merkwürdige ist, dass in der Ausgabe werde ich eine Zeile, wo der resultierende Name „bobjames“ ist und eine andere, wo der Position „devsys“. Obwohl die Rechnung nicht im Namensdatenrahmen erscheint, erscheint sie schließlich im resultierenden Datenrahmen. Also brauche ich wirklich einen Weg zu sagen, einen Wert in diesem anderen Datenrahmen zu suchen und wenn Sie etwas finden, das auf diese Spalten passt.

+0

tun Sie 'kombiniert wollen = pd.merge (Namen, info, wie = 'äußeren')'? – EdChum

+2

Sie müssen das Ergebnis von 'fillna' oder pass param' inplace = True' also 'what = what.fillna ('unknown')' oder 'what.fillna ('unknown', inplace = True)' – EdChum

+1

'bobjames zuweisen 'und' devsys 'werden durch fehlende Kommas in Ihren Eingabedaten verursacht (wahrscheinlich ein Tippfehler). "Rechnung" erscheint, weil Sie äußere Zusammenführung verwenden. Verwenden Sie how = 'left', wenn Sie nur die Werte von Namen mit optionalen Werten aus info möchten. –

Antwort

11

Ich glaube, Sie einen outermerge ausführen möchten:

In [60]: 

pd.merge(names, info, how='outer') 
Out[60]: 
    names position classification 
0  bob  dev   NaN 
1 frank  dev   thief 
2 james  dev   NaN 
3  tim  sys   good 
4 ricardo  sys   NaN 
5  mike  sys   NaN 
6  mark  sup   thief 
7  joan  sup   NaN 
8  joe  sup   thief 

Es Abschnitt ist die Art der Verschmelzungen zeigt ausführen: http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging

+0

Danke dafür, aber ich habe immer noch Probleme damit zu bekommen, was ich will. Ich habe meine Frage mit mehr Kontext aktualisiert. –

10

Falls Sie noch auf der Suche nach einer Antwort für diese:

Die "seltsamen" Dinge, die Sie beschrieben haben, sind auf einige kleinere Fehler in Ihrem Code zurückzuführen. Die erste (Erscheinung von "bobjames" und "devsys") ist zum Beispiel darauf zurückzuführen, dass Sie in Ihren Quelldatenrahmen kein Komma zwischen diesen beiden Werten haben. Und das zweite ist, weil pandas sich nicht um den Namen Ihres Datenrahmens kümmert, sondern sich um den Namen Ihrer Spalten beim Zusammenführen kümmert (Sie haben einen Datenrahmen namens "Namen", aber auch Ihre Spalten heißen "Namen"). Ansonsten scheint es, dass die Zusammenführung genau das tut, was Sie suchen:

import pandas as pd 
names = pd.DataFrame({'names':['bob','frank','bob','bob','bob', 'james','tim','ricardo','mike','mark','joan','joe'], 
         'position':['dev','dev','dev','dev','dev','dev', 'sys','sys','sys','sup','sup','sup']}) 

info = pd.DataFrame({'names':['joe','mark','tim','frank','joe','bill'], 
        'classification':['thief','thief','good','thief','good','thief']}) 
what = pd.merge(names, info, how="outer") 
what.fillna('unknown', inplace=True) 

welche bewirkt:

 names position classification 
0  bob  dev  unknown 
1  bob  dev  unknown 
2  bob  dev  unknown 
3  bob  dev  unknown 
4  frank  dev   thief 
5  james  dev  unknown 
6  tim  sys   good 
7 ricardo  sys  unknown 
8  mike  sys  unknown 
9  mark  sup   thief 
10  joan  sup  unknown 
11  joe  sup   thief 
12  joe  sup   good 
13  bill unknown   thief 
0

Betrachten Sie es als eine SQL-Operation teilnehmen. Sie benötigen eine left-outer beitreten [1].

names = pd.DataFrame({'names':['bob','frank','james','tim','ricardo','mike','mark','joan','joe'],'position':['dev','dev','dev','sys','sys','sys','sup','sup','sup']})

info = pd.DataFrame({'names':['joe','mark','tim','frank'],'classification':['thief','thief','good','thief']})

Da es names für die es keine classification ist, ein left-outer beitreten wird die Arbeit machen.

a = pd.merge(names, info, how='left', on='names')

Das Ergebnis ist ...

>>> a 
    names position classification 
0  bob  dev   NaN 
1 frank  dev   thief 
2 james  dev   NaN 
3  tim  sys   good 
4 ricardo  sys   NaN 
5  mike  sys   NaN 
6  mark  sup   thief 
7  joan  sup   NaN 
8  joe  sup   thief 

... und das ist gut. Alle NaN Ergebnisse sind in Ordnung, wenn Sie beide Tabellen betrachten.

Prost!

[1] - http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging

Verwandte Themen