it-swarm.com.de

pandas mischen Datenrahmen mit NaN (oder "unbekannt") für fehlende Werte

Ich habe 2 Datenrahmen, von denen einer zusätzliche Informationen für einige (aber nicht alle) Zeilen in den anderen enthält.

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 möchte die Klassifizierungsspalte aus dem info-Datenrahmen oben entnehmen und dem names-Datenrahmen oben hinzufügen. Wenn ich jedoch combined = pd.merge(names, info) mache, ist der resultierende Datenrahmen nur 4 Zeilen lang. Alle Zeilen, die keine Zusatzinformationen enthalten, werden gelöscht.

Idealerweise hätte ich die Werte in diesen fehlenden Spalten auf "unbekannt" gesetzt. Das Ergebnis ist ein Datenrahmen, in dem einige Leute Dieben sind, andere gut sind und der Rest unbekannt ist.

BEARBEITEN: Eine der ersten Antworten, die ich erhielt, schlug vor, Merge-Outter zu verwenden, der 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 Seltsame ist, dass ich in der Ausgabe eine Zeile bekomme, in der der Name "bobjames" und in einer anderen Position "devsys" steht. Auch wenn die Rechnung nicht im Namen dataframe enthalten ist, wird sie im resultierenden Dataframe angezeigt. Ich brauche also wirklich eine Möglichkeit, einen Wert in diesem anderen Datenrahmen nachzuschlagen, und wenn Sie etwas in diesen Spalten finden.

26
Kevin Thompson

Falls Sie noch eine Antwort dafür suchen:

Die "seltsamen" Dinge, die Sie beschrieben haben, sind auf kleinere Fehler in Ihrem Code zurückzuführen. Das erste (Auftreten von "Bobjames" und "Devsys") ist beispielsweise darauf zurückzuführen, dass zwischen den beiden Werten in Ihren Quell-Datenrahmen kein Komma steht. Der zweite Grund ist, dass Pandas sich nicht um den Namen Ihres Datenrahmens kümmern, sondern sich beim Zusammenführen um den Namen Ihrer Spalten kümmern (Sie haben einen Datenrahmen namens "Namen", aber auch Ihre Spalten werden "Namen" genannt). Ansonsten scheint die Zusammenführung genau das zu tun, wonach 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)

was führt zu:

      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
14
oxtay

Ich denke, Sie möchten eine outermerge ausführen:

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 gibt einen Abschnitt, der die Art der Zusammenführungen zeigt: http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging

14
EdChum

Stellen Sie es sich als eine SQL-Join-Operation vor. Sie benötigen einen left-outer - Join [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 gibt, für die es kein classification gibt, übernimmt ein Join left-outer Die Aufgabe.

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

... was in Ordnung ist. Alle Ergebnisse von NaN sind in Ordnung, wenn Sie sich beide Tabellen ansehen.

Prost!

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

0
Lucas Aimaretto