Si usted vino aquí en busca de información sobre cómo combinar una
DataFrameySeriesen el índice , por favor vaya a 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 conocer 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]
a b s1 s2
0 1 3 5 6
1 2 4 5 6
¿Alguien puede sugerir una mejor sintaxis / un método más rápido?
Mis intentos:
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 destacaron un problema con mi pregunta, así que 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
a b s1 s2
3 NaN 4 5 6
5 2 5 5 6
6 3 6 5 6

dfys, esta respuesta me devuelve un marco de datos vacío, no el resultado solicitado en la pregunta. No queremos hacer coincidir en el índice; queremos transmitir lossvalores a todas las filas dedf.He aquí una forma:
df.join(pd.DataFrame(s).T).fillna(method='ffill')Para analizar lo que sucede aquí ...
pd.DataFrame(s).Tcrea un DataFrame de una filasque se ve así:s1 s2 0 5 6A continuación,
joinconcatena este nuevo marco condf:a b s1 s2 0 1 3 5 6 1 2 4 NaN NaNPor último, los
NaNvalores en el índice 1 se rellenan con los valores anteriores en la columna usandofillnaelffillargumento forward-fill ( ):a b s1 s2 0 1 3 5 6 1 2 4 5 6Para evitar el uso
fillna, es posible usarpd.concatpara repetir las filas del DataFrame construido a partir des. 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))sse transforma en un DataFrame repitiendo los valores y remodelando (especificando el orden 'Fortran'), y también pasando los nombres de columna y el índice apropiados. A continuación, se une este nuevo DataFramedf.fuente
NaNvalores.index=[3, 5]las nuevas columnas contienen nan después de su comando.2debería serlen(df)de aplicación general.Si pudiera sugerirle que configure sus marcos de datos como este (autoindexación):
df = pd.DataFrame({'a':[np.nan, 1, 2], 'b':[4, 5, 6]})luego puede configurar sus valores s1 y s2 así (usando shape () para devolver el número de filas de df):
s = pd.DataFrame({'s1':[5]*df.shape[0], 's2':[6]*df.shape[0]})entonces el resultado que desea es fácil:
display (df.merge(s, left_index=True, right_index=True))Alternativamente, simplemente agregue los nuevos valores a su marco de datos df:
df = pd.DataFrame({'a':[nan, 1, 2], 'b':[4, 5, 6]}) df['s1']=5 df['s2']=6 display(df)Ambos regresan:
a b s1 s2 0 NaN 4 5 6 1 1.0 5 5 6 2 2.0 6 5 6Si 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']entonces puedes adjuntar esto de la misma manera:
df['s1']=s1devoluciones:
a b s1 0 NaN 4 a 1 1.0 5 b 2 2.0 6 cfuente
Puede establecer fácilmente una columna pandas.DataFrame en una constante. Esta constante puede ser un int como en su ejemplo. Si la columna que especifica no está en el df, los pandas crearán una nueva columna con el nombre que especifique. Entonces, después de que se construya su marco de datos, (de su pregunta):
df = pd.DataFrame({'a':[np.nan, 2, 3], 'b':[4, 5, 6]}, index=[3, 5, 6])Puedes simplemente ejecutar:
df['s1'], df['s2'] = 5, 6Puede escribir un bucle o comprensión para que haga 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.
fuente
Si
dfes un,pandas.DataFrameentoncesdf['new_col']= Series list_object of length len(df)agregará el objeto de lista o Serie como una columna nombrada'new_col'.df['new_col']= scalar(como 5 o 6 en su caso) también funciona y es equivalente adf['new_col']= [scalar]*len(df)Entonces, un código de dos líneas sirve para el propósito:
df = pd.DataFrame({'a':[1, 2], 'b':[3, 4]}) s = pd.Series({'s1':5, 's2':6}) for x in s.index: df[x] = s[x] Output: a b s1 s2 0 1 3 5 6 1 2 4 5 6fuente