web-dev-qa-db-fra.com

Création d'un pandas DataFrame à partir de colonnes d'autres DataFrames avec des index similaires

J'ai 2 DataFrames df1 et df2 avec les mêmes noms de colonne ['a', 'b', 'c'] et indexés par dates. L'index de date peut avoir des valeurs similaires. Je souhaite créer un DataFrame df3 avec uniquement les données des colonnes ['c'] renommées respectivement 'df1' et 'df2' et avec le bon index de date. Mon problème est que je ne peux pas obtenir comment fusionner l'index correctement.

df1 = pd.DataFrame(np.random.randn(5,3), index=pd.date_range('01/02/2014',periods=5,freq='D'), columns=['a','b','c'] )
df2 = pd.DataFrame(np.random.randn(8,3), index=pd.date_range('01/01/2014',periods=8,freq='D'), columns=['a','b','c'] )
df1
                 a        b            c
2014-01-02   0.580550    0.480814    1.135899
2014-01-03  -1.961033    0.546013    1.093204
2014-01-04   2.063441   -0.627297    2.035373
2014-01-05   0.319570    0.058588    0.350060
2014-01-06   1.318068   -0.802209   -0.939962

df2
                 a        b            c
2014-01-01   0.772482    0.899337    0.808630
2014-01-02   0.518431   -1.582113    0.323425
2014-01-03   0.112109    1.056705   -1.355067
2014-01-04   0.767257   -2.311014    0.340701
2014-01-05   0.794281   -1.954858    0.200922
2014-01-06   0.156088    0.718658   -1.030077
2014-01-07   1.621059    0.106656   -0.472080
2014-01-08  -2.061138   -2.023157    0.257151

Le DataFrame df3 devrait avoir la forme suivante:

df3
                 df1        df2
2014-01-01   NaN        0.808630
2014-01-02   1.135899   0.323425
2014-01-03   1.093204   -1.355067
2014-01-04   2.035373   0.340701
2014-01-05   0.350060   0.200922
2014-01-06   -0.939962  -1.030077
2014-01-07   NaN        -0.472080
2014-01-08   NaN        0.257151

Mais avec NaN dans la colonne df1, l’index de date de df2 est plus large. (Dans cet exemple, j'obtiendrais NaN pour les dates suivantes: 2014-01-01, 2014-01-07 and 2014-01-08)

Merci de votre aide.

37
user3153467

Vous pouvez utiliser concat :

In [11]: pd.concat([df1['c'], df2['c']], axis=1, keys=['df1', 'df2'])
Out[11]: 
                 df1       df2
2014-01-01       NaN -0.978535
2014-01-02 -0.106510 -0.519239
2014-01-03 -0.846100 -0.313153
2014-01-04 -0.014253 -1.040702
2014-01-05  0.315156 -0.329967
2014-01-06 -0.510577 -0.940901
2014-01-07       NaN -0.024608
2014-01-08       NaN -1.791899

[8 rows x 2 columns]

L'argument d'axe détermine la manière dont les DataFrames sont empilés:

df1 = pd.DataFrame([1, 2, 3])
df2 = pd.DataFrame(['a', 'b', 'c'])

pd.concat([df1, df2], axis=0)
   0
0  1
1  2
2  3
0  a
1  b
2  c

pd.concat([df1, df2], axis=1)

   0  0
0  1  a
1  2  b
2  3  c
57
Andy Hayden

Eh bien, je ne suis pas sûr que cette fusion soit la voie à suivre. Personnellement, je construirais un nouveau cadre de données en créant un index des dates, puis en construisant les colonnes à l'aide de listes de compréhension. Peut-être pas la manière la plus pythonique, mais cela semble fonctionner pour moi!

import pandas as pd
import numpy as np

df1 = pd.DataFrame(np.random.randn(5,3), index=pd.date_range('01/02/2014',periods=5,freq='D'), columns=['a','b','c'] )
df2 = pd.DataFrame(np.random.randn(8,3), index=pd.date_range('01/01/2014',periods=8,freq='D'), columns=['a','b','c'] )

# Create an index list from the set of dates in both data frames
Index = list(set(list(df1.index) + list(df2.index)))
Index.sort()

df3 = pd.DataFrame({'df1': [df1.loc[Date, 'c'] if Date in df1.index else np.nan for Date in Index],\
                'df2': [df2.loc[Date, 'c'] if Date in df2.index else np.nan for Date in Index],},\
                index = Index)

df3
5
Woody Pride