J'ai un tableau avec les ventes et les prévisions par mois pour des milliers de produits à travers 2015 - 2017. Mes données donne la demande & Prévisions pour chaque site, type, produit et date (seulement les moisRemplir tous les mois pour les données multiindex dans pandas
Le problème est que s'il n'y a pas de ventes & aucune prévision dans un mois je ne vois pas la ligne spécifique. Dans l'exemple ci-dessous, vous voyez que la ligne pour "2015-08-31" est manquante. Je voudrais voir pour cette ligne une demande de 0 et une prévision de 0. (Voir ci-dessous un exemple avec df_expected).
Fondamentalement, je voudrais remplir ce tableau avec 0 pour toutes les dates entre 2015-06-30 à 2017-09-30 pour toutes les combinaisons produit/type/site.
Comme vous pouvez le voir dans le code, je n'ai défini aucun index, mais fondamentalement ["Site", "Type", "Product", "Date"] pourrait être vu comme le multiIndex.
Notez que j'ai des millions de lignes.
import pandas as pd
data = [("W1","G1",1234,pd.to_datetime("2015-07-31"),8,4),
("W1","G1",1234,pd.to_datetime("2015-09-30"),2,4),
("W1","G1",1234,pd.to_datetime("2015-10-31"),2,4),
("W1","G1",1234,pd.to_datetime("2015-11-30"),4,4),
("W1","G2",2345,pd.to_datetime("2015-07-31"),5,0),
("W1","G2",2345,pd.to_datetime("2015-08-31"),1,3),
("W1","G2",2345,pd.to_datetime("2015-10-31"),1,3),
("W1","G2",2345,pd.to_datetime("2015-11-30"),3,3)]
labels = ["Site","Type","Product","Date","Demand","Forecast"]
df = pd.DataFrame(data,columns=labels)
df
Site Type Product Date Demand Forecast
0 W1 G1 1234 2015-07-31 8 4
1 W1 G1 1234 2015-09-30 2 4
2 W1 G1 1234 2015-10-31 2 4
3 W1 G1 1234 2015-11-30 4 4
4 W1 G2 2345 2015-07-31 5 0
5 W1 G2 2345 2015-08-31 1 3
6 W1 G2 2345 2015-10-31 1 3
7 W1 G2 2345 2015-11-30 3 3
Ceci est le résultat que je attends
data_expected = [("W1","G1",1234,pd.to_datetime("2015-07-31"),8,4),
("W1","G1",1234,pd.to_datetime("2015-08-31"),0,0),
("W1","G1",1234,pd.to_datetime("2015-09-30"),2,4),
("W1","G1",1234,pd.to_datetime("2015-10-31"),2,4),
("W1","G1",1234,pd.to_datetime("2015-11-30"),4,4)]
df_expected = pd.DataFrame(data_expected,columns=labels)
df_expected
Site Type Product Date Demand Forecast
0 W1 G1 1234 2015-07-31 8 4
1 W1 G1 1234 2015-08-31 0 0
2 W1 G1 1234 2015-09-30 2 4
3 W1 G1 1234 2015-10-31 2 4
4 W1 G1 1234 2015-11-30 4 4
Je pensais à l'origine à propos de la pile/désempiler pour vous assurer que j'ai tous les mois. Mais ce n'est pas optimal pour une base de données avec des millions de lignes.
df = (df
.set_index("Date")
.groupby(["Site","Product","Type",pd.TimeGrouper('M')])[["Forecast","Demand"]].sum()
.unstack()
.fillna(0)
.astype(int))
Qu'en pensez-vous?
Il semble que ma solution avec pile/Désempiler est plus rapide. Avec ta technique cela fonctionne pour df avec 10 000 lignes. Mais si vous exécutez cela sur 1 million de lignes cela prend beaucoup de temps (je n'ai jamais vu la solution) – Nicolas
Maintenant, je comprends. Je peux seulement améliorer votre solution - '(df.set_index (" Date ") .groupby ([" Site "," Produit "," Type ", pd.TimeGrouper ('M')]) ['Demande', ' Prévision ']. Sum() .unstack (fill_value = 0) .stack()) '- Est-il plus rapide avec vos données réelles? Si oui, je peux l'ajouter à ma réponse. – jezrael
oui c'est beaucoup plus rapide avec ce désempilage/pile – Nicolas