2015-01-27 15 views
14

Ho 2 dataframes, uno dei quali ha informazioni supplementari per alcune (ma non tutte) delle righe nell'altra.panda si uniscono dataframe riempire i valori mancanti

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']}) 

vorrei prendere la colonna di classificazione da info dataframe sopra e aggiungerlo alla names dataframe sopra. Tuttavia, quando faccio combined = pd.merge(names, info) il dataframe risultante è lungo solo 4 righe. Tutte le righe che non hanno informazioni supplementari vengono eliminate.

Idealmente, avrei i valori in quelle colonne mancanti impostate su sconosciuto. Risultante in un dataframe in cui alcune persone sono teive, alcune sono buone e il resto è sconosciuto.

MODIFICA: Una delle prime risposte che ho ricevuto suggeriva di usare l'esterno di fusione che sembra fare alcune cose strane. Ecco un esempio di codice:

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

La cosa strana è che in uscita prendo una riga in cui il nome risultante è "bobjames" e un altro in cui posizione è "devsys". Infine, anche se la fattura non appare nel nome del dataframe, compare nel dataframe risultante. Quindi ho davvero bisogno di un modo per dire di cercare un valore in questo altro dataframe e se trovi qualcosa di appiccicoso su quelle colonne.

+0

Vuoi 'combinati = pd.merge (nomi, informazioni, come = 'esterno')'? – EdChum

+2

Devi assegnare il risultato di 'fillna' o passare param' inplace = True' così 'what = what.fillna ('unknown')' o 'what.fillna ('unknown', inplace = True)' – EdChum

+1

'bobjames 'e' devsys 'sono causati da virgole mancanti nei dati di input (probabilmente un refuso). "bill" viene visualizzato perché si utilizza l'unione esterna. Usa how = 'left' se vuoi solo i valori dei nomi con valori opzionali da info. –

risposta

11

penso che si desidera eseguire un outermerge:

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 

C'è la sezione che mostra il tipo di fusioni in grado di eseguire: http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging

+0

Grazie per quello, ma sto ancora avendo qualche problema a ottenere quello che voglio. Ho aggiornato la mia domanda con più contesto. –

10

Nel caso in cui si sta ancora cercando una risposta per questo:

Le "strane" cose che hai descritto sono dovute ad alcuni errori minori nel tuo codice. Ad esempio, il primo (aspetto di "bobjames" e "devsys") è dovuto al fatto che non hai una virgola tra questi due valori nei tuoi dataframes di origine. E il secondo è perché i panda non si preoccupano del nome del tuo dataframe ma si preoccupa del nome delle tue colonne quando si uniscono (hai un dataframe chiamato "nomi" ma anche le tue colonne sono chiamate "nomi"). In caso contrario, sembra che l'unione sta facendo esattamente quello che stai cercando:

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) 

che si tradurrà in:

 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

pensare ad esso come uno SQL join. È necessario un join left-outer [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']})

Poiché non vi sono names per i quali non v'è alcuna classification, un left-outer join farà il lavoro.

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

Il risultato è ...

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

... che va bene. Tutti i risultati di NaN sono ok se guardi entrambi i tavoli.

Cheers!

[1]

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

Problemi correlati