2012-06-10 33 views
19

Tengo un pandas DataFrame que tiene varias columnas en ella:pandas: combinar dos columnas de una trama de datos

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) 

donde foo y bar son columnas que contienen los mismos datos todavía se nombran de manera diferente. ¿Hay alguna manera de mover las filas que componen foo en bar, idealmente manteniendo el nombre de bar?

Al final, la trama de datos debería aparecer como:

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) 

Eso es los valores NaN que componían la barra fueron reemplazados por los valores de foo.

Respuesta

21

Prueba esto:

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

Si desea que los datos se conviertan en la nueva columna bar, simplemente asigna el resultado a df['bar'].

+0

no estoy viendo 'concat' en función del espacio de nombres pandas; No estoy seguro de lo que me estoy perdiendo. – BFTM

+0

¿Qué versión de pandas tienes? La función está documentada aquí: http://pandas.pydata.org/pandas-docs/stable/merging.html#concatenating-objects – BrenBarn

+0

Estaba ejecutando pandas ver 0.6.1 que no tiene incluida la función concat. Una actualización a v 0.7.3 trae concat en el espacio de nombres. ¡Funciona de maravilla! Gracias. – BFTM

21

puede utilizar directamente fillna y asignar el resultado a la 'barra' columna

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

ejemplo general:

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

pero tenga en cuenta que dado que filldf está indexado en 0..3 mientras dftot está indexado en 1..4, dftot.fillna (filldf) ['a'] [4] será nan. no 7.0 –

5

Otra opción, utilice el método .apply() en el marco. Usted puede hacer reasignar una columna con deferencia a los datos existentes ...

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

Gracias por la captura @Veenit – openwonk

3

Las versiones más modernas pandas (desde al menos 0,12) tienen los métodos para combine_first() and update() objetos trama de datos y series. Por ejemplo si su trama de datos se llama df, que haría:

df.bar.combine_first(df.foo) 

que sólo alteraría los valores de la columna Nan bar para que coincida con la columna de la foo, y que lo haría in-situ. Para sobrescribir los valores que no son Nan en bar con los del foo, debe utilizar el método update().

2

Puede hacerlo también usando numpy.

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

Cuestiones relacionadas