Cómo fusionar una serie y un dataframe

Si vino aquí buscando información sobre cómo combinar un DataFrame y una Series en el índice , mire esta respuesta .

La intención original del OP era preguntar cómo asignar elementos de serie como columnas a otro DataFrame . Si está interesado en saber la respuesta a esto, mire la respuesta aceptada por EdChum.


Lo mejor que se me ocurre es

 df = pd.DataFrame({'a':[1, 2], 'b':[3, 4]}) # see EDIT below s = pd.Series({'s1':5, 's2':6}) for name in s.index: df[name] = s[name] ab s1 s2 0 1 3 5 6 1 2 4 5 6 

¿Alguien puede sugerir una mejor syntax / método más rápido?

Mis bashs:

 df.merge(s) AttributeError: 'Series' object has no attribute 'columns' 

y

 df.join(s) ValueError: Other Series must have a name 

EDITAR Las dos primeras respuestas publicadas resaltaron un problema con mi pregunta, así que por favor use lo siguiente para construir df :

 df = pd.DataFrame({'a':[np.nan, 2, 3], 'b':[4, 5, 6]}, index=[3, 5, 6]) 

con el resultado final

  ab s1 s2 3 NaN 4 5 6 5 2 5 5 6 6 3 6 5 6 

Podría construir un dataframe a partir de la serie y luego fusionarse con el dataframe. Así que especifica los datos como valores, pero los multiplica por la longitud, establece las columnas en el índice y configura los parámetros para left_index e right_index en True:

 In [27]: df.merge(pd.DataFrame(data = [s.values] * len(s), columns = s.index), left_index=True, right_index=True) Out[27]: ab s1 s2 0 1 3 5 6 1 2 4 5 6 

EDITAR para la situación en la que desea que el índice de su df construido a partir de la serie utilice el índice de la df, entonces puede hacer lo siguiente:

 df.merge(pd.DataFrame(data = [s.values] * len(df), columns = s.index, index=df.index), left_index=True, right_index=True) 

Esto supone que los índices coinciden con la longitud.

Actualizar
Desde v0.24.0 en adelante, puede fusionarse en DataFrame y Series siempre y cuando se nombre la Serie.

 df.merge(s.rename('new'), left_index=True, right_index=True) # If series is already named, # df.merge(s, left_index=True, right_index=True) 

Hoy en día, simplemente puede convertir la serie a un dataframe con to_frame () . Entonces (si se une en el índice):

 df.merge(s.to_frame(), left_index=True, right_index=True) 

Aquí hay una forma:

 df.join(pd.DataFrame(s).T).fillna(method='ffill') 

Para descomponer lo que pasa aquí …

pd.DataFrame(s).T crea un DataFrame de una fila desde s que tiene este aspecto:

  s1 s2 0 5 6 

A continuación, join concatena este nuevo marco con df :

  ab s1 s2 0 1 3 5 6 1 2 4 NaN NaN 

Por último, los valores de NaN en el índice 1 se llenan con los valores anteriores en la columna usando fillna con el argumento forward-fill ( ffill ):

  ab s1 s2 0 1 3 5 6 1 2 4 5 6 

Para evitar usar fillna , es posible usar pd.concat para repetir las filas del DataFrame construido a partir de s . En este caso, la solución general es:

 df.join(pd.concat([pd.DataFrame(s).T] * len(df), ignore_index=True)) 

Aquí hay otra solución para abordar el desafío de indexación planteado en la pregunta editada:

 df.join(pd.DataFrame(s.repeat(len(df)).values.reshape((len(df), -1), order='F'), columns=s.index, index=df.index)) 

s se transforma en un DataFrame repitiendo los valores y remodelando (especificando el orden de ‘Fortran’), y también pasando los nombres e índices de columna apropiados. Este nuevo DataFrame se une a df .

Si pudiera sugerir la configuración de sus marcos de datos como este (auto-indexación):

 df = pd.DataFrame({'a':[np.nan, 1, 2], 'b':[4, 5, 6]}) 

luego, puede configurar sus valores s1 y s2 (usando shape () para devolver el número de filas desde df):

 s = pd.DataFrame({'s1':[5]*df.shape[0], 's2':[6]*df.shape[0]}) 

entonces el resultado que deseas es fácil:

 display (df.merge(s, left_index=True, right_index=True)) 

Alternativamente, simplemente agregue los nuevos valores a su df de dataframe:

 df = pd.DataFrame({'a':[nan, 1, 2], 'b':[4, 5, 6]}) df['s1']=5 df['s2']=6 display(df) 

Ambos vuelven:

  ab s1 s2 0 NaN 4 5 6 1 1.0 5 5 6 2 2.0 6 5 6 

Si tiene otra lista de datos (en lugar de un solo valor para aplicar), y sabe que está en la misma secuencia que df, por ejemplo:

 s1=['a','b','c'] 

A continuación, puede adjuntar esto de la misma manera:

 df['s1']=s1 

devoluciones:

  ab s1 0 NaN 4 a 1 1.0 5 b 2 2.0 6 c 

Puede establecer fácilmente una columna pandas.DataFrame en una constante. Esta constante puede ser un int como en tu ejemplo. Si la columna que especifica no está en la df, entonces los pandas crearán una nueva columna con el nombre que especifique. Así que después de que se construya su dataframe, (de su pregunta):

 df = pd.DataFrame({'a':[np.nan, 2, 3], 'b':[4, 5, 6]}, index=[3, 5, 6]) 

Usted puede simplemente ejecutar:

 df['s1'], df['s2'] = 5, 6 

Podría escribir un bucle o una comprensión para hacer esto para todos los elementos en una lista de tuplas, o claves y valores en un diccionario, dependiendo de cómo tenga almacenados sus datos reales.