2012-06-10 31 views
19

Ho una pandi DataFrame con più colonne in esso:pandi: combinare due colonne in un dataframe

Index: 239897 entries, 2012-05-11 15:20:00 to 2012-06-02 23:44:51 
Data columns: 
foo     11516 non-null values 
bar     228381 non-null values 
Time_UTC    239897 non-null values 
dtstamp    239897 non-null values 
dtypes: float64(4), object(1) 

dove foo e bar sono colonne che contengono gli stessi dati ancora sono denominati in modo diverso. C'è un modo per spostare le righe che compongono foo in bar, idealmente pur mantenendo il nome di bar?

Alla fine il dataframe dovrebbe apparire come:

Index: 239897 entries, 2012-05-11 15:20:00 to 2012-06-02 23:44:51 
Data columns: 
bar     239897 non-null values 
Time_UTC    239897 non-null values 
dtstamp    239897 non-null values 
dtypes: float64(4), object(1) 

Cioè i valori NaN che componevano bar sono stati sostituiti dai valori da foo.

risposta

21

Prova questa:

pandas.concat([df['foo'].dropna(), df['bar'].dropna()]).reindex_like(df) 

Se si desidera che i dati diventino la nuova colonna bar, basta assegnare il risultato alla df['bar'].

+0

non sto vedendo 'concat' in funzione nello spazio dei nomi panda; Non sono sicuro di cosa mi stia perdendo. – BFTM

+0

Quale versione di panda hai? La funzione è documentata qui: http://pandas.pydata.org/pandas-docs/stable/merging.html#concatenating-objects – BrenBarn

+0

Ero in esecuzione pandas ver 0.6.1 che non ha la funzione concat inclusa. Un aggiornamento alla v 0.7.3 porta concat nello spazio dei nomi. Funziona come un fascino! Grazie. – BFTM

21

è possibile utilizzare direttamente fillna e assegnare il risultato alla colonna 'bar'

df['bar'].fillna(df['foo'], inplace=True) 
del df['foo'] 

generale esempio:

import pandas as pd 
#creating the table with two missing values 
df1 = pd.DataFrame({'a':[1,2],'b':[3,4]}, index = [1,2]) 
df2 = pd.DataFrame({'b':[5,6]}, index = [3,4]) 
dftot = pd.concat((df1, df2)) 
print dftot 
#creating the dataframe to fill the missing values 
filldf = pd.DataFrame({'a':[7,7,7,7]}) 

#filling 
print dftot.fillna(filldf) 
+0

ma si noti che poiché filldf è indicizzato 0..3 mentre dftot è indicizzato 1..4, dftot.fillna (filldf) ['a'] [4] sarà nan. non 7.0 –

5

Un'altra opzione, utilizzare il metodo .apply() sul telaio. Si può fare riassegnare una colonna con deferenza ai dati esistenti ...

import pandas as pd 
import numpy as np 

# get your data into a dataframe 

# replace content in "bar" with "foo" if "bar" is null 
df["bar"] = df.apply(lambda row: row["foo"] if row["bar"] == np.NaN else row["bar"], axis=1) 

# note: change 'np.NaN' with null values you have like an empty string 
+0

Grazie per la cattura @Veenit – openwonk

3

più versioni panda moderni (almeno dal 0,12) hanno le combine_first() and update() metodi per gli oggetti dataframe e Serie. Ad esempio se il vostro dataframe sono stati chiamati df, si dovrebbe fare:

df.bar.combine_first(df.foo) 

tali da modificare solo i valori Nan della colonna bar per abbinare la colonna foo, e farebbe così inplace. Per sovrascrivere i valori non Nan in bar con quelli in foo, si utilizzerà il metodo update().

2

Si può fare anche utilizzando numpy.

df['bar'] = np.where(pd.isnull(df['bar']),df['foo'],df['bar'])

Problemi correlati