2017-08-22 4 views
1

J'ai les deux blocs de données suivants que je veux fusionner.Python: fusionner une trame de données Pandas avec un tableau croisé dynamique

df1: 
    id time     station 
0  a 22.08.2017 12:00:00 A1 
1  b 22.08.2017 12:00:00 A3 
2  a 22.08.2017 13:00:00 A2 
... 

pivot: 
     station    A1  A2  A3 
0  time 
1  22.08.2017 12:00:00 10  12  11 
2  22.08.2017 13:00:00 9  7  3 
3  22.08.2017 14:00:00 2  3  4 
4  22.08.2017 15:00:00 3  2  7 
... 

il devrait ressembler à:

merge: 

    id time     station value 
0  a 22.08.2017 12:00:00 A1  10 
1  b 22.08.2017 12:00:00 A3  11 
2  a 22.08.2017 13:00:00 A2  7 
... 

Maintenant, je veux ajouter une colonne dans la trame de données à la juste valeur du tableau croisé dynamique. J'ai échoué en incluant les étiquettes de colonne pour la fusion. je construisais quelque chose comme ça, mais ça ne marche pas:

merge = pd.merge(df1, pivot, how="left", left_on=["time", "station"], right_on=["station", pivot.columns]) 

Toute aide?

EDIT:

Comme conseillé, au lieu du tableau croisé dynamique j'ai essayé d'utiliser les données suivantes:

df2: 
time     station value 
22.08.2017 12:00:00 A1  10 
22.08.2017 12:00:00 A2  12 
22.08.2017 12:00:00 A3  11 
       ... 
22.08.2017 13:00:00 A1  9 
22.08.2017 13:00:00 A2  7 
22.08.2017 13:00:00 A3  3 

Le tableau contient environ 1300 stations différentes pour chaque horodatage. Dans l'ensemble, j'ai plus de 115.000.000 lignes. Mon df1 a 5.000.000 lignes.

Maintenant, j'ai essayé de fusionner df1.head (100) et df2, mais dans le résultat toutes les valeurs sont nan. Par conséquent, je ceci:

merge = pd.merge(df1.head(100), df2, how="left", on=["time", "station"]) 

Un autre problème est que la fusion prend quelques minutes pour que j'attends l'ensemble DF1 prendra plusieurs jours.

+0

Pouvez-vous envoyer comment vous avez df2 avec des données d'échantillon? –

+0

Que voulez-vous dire par df2? Si vous appliquez à la trame de données que je veux atteindre, je découvre à quelle heure et quelle station appartient au premier identifiant. Ensuite, je compare avec le cadre de données de pivot et obtenir la valeur pour la même heure et la même station et continuer avec la ligne suivante. J'ai donc créé une boucle for, mais ce n'est pas si rapide. C'est la raison pour laquelle je veux le faire en fusionnant les données. – Timo

+0

Désolé j'ai mal interprété - 'pivot' dataframe. Avez-vous des exemples de données pour recréer ceci? Je me demande s'il y a une meilleure façon de faire pivoter cela. –

Répondre

1

Je suppose que vous avez obtenu le dataframe pivot utilisant pivot ou pivot_table en pandas géants, si vous pouvez effectuer la fusion en utilisant la trame de données que vous aviez avant le pivot, il devrait fonctionner très bien.

Sinon, vous devrez inverser le pivot à l'aide melt avant la fusion:

melt = pd.concat([pivot[['time']],pivot[['A1']].melt()],axis = 1) 
melt = pd.concat([melt,pd.concat([pivot[['time']],pivot[['A2']].melt()],axis = 1)]) 
melt = pd.concat([melt,pd.concat([pivot[['time']],pivot[['A3']].melt()],axis = 1)]) 
melt.columns = ['time','station','value'] 

Ensuite, il suffit effectuer une fusion comme vous attendiez:

my_df.merge(melt,on = ['time','station']) 

    id time station value 
0 a time1 A1  10 
1 b time1 A3  11 
2 a time2 A2  7 

EDIT:

Si vos données sont aussi grandes que dans votre édition, vous devez en effet effectuer les fusions sur des morceaux d'entre eux. Vous pourriez essayer de le réduire en morceaux à la fois vos données.

D'abord, triez vos df1 afin d'avoir seulement des valeurs proches du temps:

df1.sort_values('time',inplace = True) 

Ensuite, vous morceau ce, morceau de la seconde trame de données de la façon dont vous êtes sûr d'avoir toutes les lignes que vous pourriez avoir besoin, puis fusionner ces blocs:

chunk1 = df1.head(100) 
chunk2 = df2.loc[df2.time.between(chunk1.time.min(),chunk1.time.max())] 
merge = chunk1.merge(chunk2,on = ['time','station'],how = 'left') 
+0

Cela pourrait être une bonne solution. Je vais essayer demain. Peut-être qu'il y aura un problème de "temps", car le cadre de données d'origine contient quelques millions de lignes. Par conséquent, j'ai espéré que le tableau croisé dynamique est plus utile pour une fusion rapide. – Timo

+0

Si votre problème concerne un problème de calcul, envisagez peut-être de regrouper vos données par section de temps et de fusionner ces parties avant de les concaténer. De cette façon, vous effectuerez plusieurs fusions plus petites. Il sera un code un peu plus long, mais vous permettra d'économiser beaucoup de temps. – ysearka

+0

J'ai essayé de fusionner la df avec les données d'origine mais les valeurs dans le résultat sont nan. J'ai développé ma description ci-dessus. Savez-vous pourquoi il n'y a pas les bonnes valeurs? – Timo