posada
Esta pregunta se ha hecho tantas veces, y parece funcionar para otros, sin embargo, me estoy poniendo NaN
valores cuando copio una columna de un DataFrame diferente (df1
y df2
tienen la misma longitud).
df1
date hour var1
a 2017-05-01 00:00:00 456585
b 2017-05-01 01:00:00 899875
c 2017-05-01 02:00:00 569566
d 2017-05-01 03:00:00 458756
e 2017-05-01 04:00:00 231458
f 2017-05-01 05:00:00 986545
df2
MyVar1 MyVar2
0 6169.719338 3688.045368
1 5861.148007 3152.238704
2 5797.053347 2700.469871
3 5779.102340 2730.471948
4 6708.219647 3181.298291
5 8550.380343 3793.580394
Necesito así en mi df2
MyVar1 MyVar2 date hour
0 6169.719338 3688.045368 2017-05-01 00:00:00
1 5861.148007 3152.238704 2017-05-01 01:00:00
2 5797.053347 2700.469871 2017-05-01 02:00:00
3 5779.102340 2730.471948 2017-05-01 03:00:00
4 6708.219647 3181.298291 2017-05-01 04:00:00
5 8550.380343 3793.580394 2017-05-01 05:00:00
Intenté lo siguiente,
df2['date'] = df1['date']
df2['hour'] = df1['hour']
type(df1)
>> pandas.core.frame.DataFrame
type(df2)
>> pandas.core.frame.DataFrame
Estoy recibiendo lo siguiente,
MyVar1 MyVar2 date hour
0 6169.719338 3688.045368 NaN NaN
1 5861.148007 3152.238704 NaN NaN
2 5797.053347 2700.469871 NaN NaN
¿Por qué está pasando esto? Hay otro post que habla merge
, pero solo necesito copiarlo. Cualquier ayuda sería apreciada.
cs95
El culpable son los índices que no se pueden alinear
Los índices de sus DataFrames son diferentes (y, en consecuencia, los índices de cada columna), por lo que al intentar asignar una columna de un DataFrame a otro, pandas intentará alinear los índices y, al no hacerlo, insertará NaNs.
Considere los siguientes ejemplos para entender lo que esto significa:
# Setup
A = pd.DataFrame(index=['a', 'b', 'c'])
B = pd.DataFrame(index=['b', 'c', 'd', 'f'])
C = pd.DataFrame(index=[1, 2, 3])
# Example of alignable indexes - A & B (complete or partial overlap of indexes)
A.index B.index
a
b b (overlap)
c c (overlap)
d
f
# Example of unalignable indexes - A & C (no overlap at all)
A.index C.index
a
b
c
1
2
3
Cuando no hay superposiciones, los pandas no pueden hacer coincidir ni un solo valor entre los dos DataFrames para ingresar el resultado de la asignación, por lo que la salida es una columna llena de NaN.
Si está trabajando en una computadora portátil IPython, puede verificar que esta sea la causa principal usando,
df1.index.equals(df2.index)
# False
df1.index.intersection(df2.index).empty
# True
Puede usar cualquiera de las siguientes soluciones para solucionar este problema.
Solución 1: restablezca los índices de ambos DataFrames
Es posible que prefiera esta opción si no tenía la intención de tener índices diferentes en primer lugar, o si no le importa particularmente conservar el índice.
# Optional, if you want a RangeIndex => [0, 1, 2, ...]
# df1.index = pd.RangeIndex(len(df))
# Homogenize the index values,
df2.index = df1.index
# Assign the columns.
df2[['date', 'hour']] = df1[['date', 'hour']]
Si desea mantener el índice existente, pero como una columna, puede usar reset_index()
en cambio.
Solución 2: asigne matrices NumPy (omita la alineación del índice)
Esta solución solo funcionará si las longitudes de los dos DataFrames coinciden.
# pandas >= 0.24
df2['date'] = df1['date'].to_numpy()
# pandas < 0.24
df2['date'] = df1['date'].values
Para asignar múltiples columnas fácilmente, use,
df2[['date', 'hour']] = df1[['date', 'hour']].to_numpy()
-
@innm Podría ser un problema con su index. Intenta agregar
ignore_index=True
? De lo contrario, restablezca primero ambos índices y luego concatene.– cs95
18 de agosto de 2017 a las 2:35
-
@innm prueba
df2['date'] = df1['date'].values
– BENY
18 de agosto de 2017 a las 2:37
-
@innm Ah, lo adiviné. Los índices no eran idénticos.
– cs95
18 de agosto de 2017 a las 2:40
-
Tenía dos marcos de datos donde uno tenía un índice de rango y el otro tenía un índice entero con valores dentro de ese rango. Mirando los marcos de datos, los índices parecen estar bien, pero la intersección estaba vacía. Así que tuve que usar to_numpy() en su lugar.
– Lyte FM
14 de noviembre de 2019 a las 20:54
-
¿Alguna idea de cómo hacer que los nombres de las columnas sean dinámicos, en lugar de uno codificado?
– Manu Batham
19 de febrero a las 7:04
Prueba esto ?
df2['date'] = df1['date'].values
df2['hour'] = df1['hour'].values
-
¡Esto es mejor que la solución aceptada!
– Gokul nath
16 de septiembre de 2021 a las 9:02
-
cuando los datos son grandes (alrededor de 10 ^ 5), son muy lentos, ¿hay alguna forma?
– lemmingxuan
16 de noviembre de 2021 a las 13:56
Sé que llego tarde a este hilo, pero este formato me ha funcionado bien.
df2.insert(1, value=df1['Name'], column='Name')
también puede realizar funciones en df1 en ese argumento de conjunto de valores. Espero que esto ayude