web-dev-qa-db-fra.com

Copier une colonne d'un DataFrame vers un autre donne des valeurs NaN?

Cette question a été posée à maintes reprises, et cela a semblé fonctionner pour d'autres. Cependant, je reçois des valeurs de NaN lorsque je copie une colonne d'un autre DataFrame (df1 et df2 sont de même longueur).

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

J'ai besoin de ça dans mon 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

J'ai essayé ce qui suit,

df2['date'] = df1['date']
df2['hour'] = df1['hour']

type(df1)
>> pandas.core.frame.DataFrame

type(df2)
>> pandas.core.frame.DataFrame

Je reçois ce qui suit,

       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

Pourquoi cela arrive-t-il? Il y a un autre post qui parle de merge, mais je dois juste le copier. Toute aide serait appréciée.

20
i.n.n.m

Le coupable est les index inalignables

Les index de vos DataFrames sont différents (et en conséquence, les index de chaque colonne), donc lorsque vous essayez d'affecter une colonne d'un DataFrame à un autre, les pandas essaieront d'aligner les index, et à défaut, insérez NaNs.

Considérez les exemples suivants pour comprendre ce que cela signifie:

# 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

En l'absence de chevauchement, pandas ne peut pas correspondre à une seule valeur entre les deux DataFrames à insérer dans le résultat de l'affectation, de sorte que le résultat est une colonne contenant des NaN.

Si vous travaillez sur un ordinateur portable IPython, vous pouvez vérifier qu’il s’agit bien de la cause première en utilisant,

df1.index.equals(df2.index)                                                                                               
# False
df1.index.intersection(df2.index).empty                                                                                     
# True

Vous pouvez utiliser l’une des solutions suivantes pour résoudre ce problème.

Solution 1: réinitialisez les deux index DataFrames

Vous préférerez peut-être cette option si vous ne voulez pas avoir d’indices différents au départ, ou si vous ne tenez pas particulièrement à préserver l’indice.

# 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 vous souhaitez conserver l'index existant, mais sous forme de colonne, vous pouvez utiliser reset_index() à la place.


Solution 2: attribuer des tableaux NumPy (contourner l'alignement d'index)

Cette solution ne fonctionnera que si les longueurs des deux DataFrames correspondent.

# pandas >= 0.24
df2['date'] = df1['date'].to_numpy()
# pandas < 0.24
df2['date'] = df1['date'].values

Pour assigner facilement plusieurs colonnes, utilisez,

df2 = df2.assign(**{c: df1[c].to_numpy() for c in ('date', 'hour')})
22
cs95

Essaye ça ?

df2['date'] = df1['date'].values
df2['hour'] = df1['hour'].values
15
WeNYoBen