J'ai des données de prix pour les pièces qui sont mises à jour tous les mois. Il a été intégré à un dataframe pandas. Parfois, une pièce ne recevra pas de prix pendant un certain mois, auquel cas je voudrais la remplacer par le prix de cette pièce du mois précédent.
Dans le cas où le mois précédent a également un prix manquant pour cette pièce, je souhaite continuer à chercher en arrière jusqu'à ce qu'un prix valide soit trouvé, auquel cas ce prix devrait se propager jusqu'à ce qu'un prix valide soit trouvé.
Si aucun prix valide n'est trouvé pour cette pièce, je souhaite que cette pièce soit entièrement supprimée de la base de données.
Si le premier nombre de mois contient des prix manquants pour une certaine partie, je voudrais supprimer ces lignes afin que le premier enregistrement soit toujours un prix valide.
Essentiellement, je veux remplir la colonne de prix en tenant compte des numéros de pièce.
À titre d'exemple, je commencerais par quelque chose comme ceci:
part price date 1 67.32 2018-12-01 00:00:00.000 3 99.16 2018-12-01 00:00:00.000 1 67.32 2018-11-01 00:00:00.000 3 167.34 2018-11-01 00:00:00.000 1 67.32 2018-10-01 00:00:00.000 3 167.34 2018-10-01 00:00:00.000 1 88.37 2018-09-01 00:00:00.000 3 212.70 2018-09-01 00:00:00.000 1 88.37 2018-08-01 00:00:00.000 3 264.02 2018-08-01 00:00:00.000 1 88.37 2018-07-01 00:00:00.000 3 264.02 2018-07-01 00:00:00.000
Et terminer par ceci:
part price date 1 NaN 2018-12-01 00:00:00.000 2 NaN 2018-12-01 00:00:00.000 3 99.16 2018-12-01 00:00:00.000 1 NaN 2018-11-01 00:00:00.000 2 NaN 2018-11-01 00:00:00.000 3 NaN 2018-11-01 00:00:00.000 1 67.32 2018-10-01 00:00:00.000 2 NaN 2018-10-01 00:00:00.000 3 167.34 2018-10-01 00:00:00.000 1 88.37 2018-09-01 00:00:00.000 2 NaN 2018-09-01 00:00:00.000 3 212.70 2018-09-01 00:00:00.000 1 88.37 2018-08-01 00:00:00.000 2 NaN 2018-08-01 00:00:00.000 3 NaN 2018-08-01 00:00:00.000 1 88.37 2018-07-01 00:00:00.000 2 NaN 2018-07-01 00:00:00.000 3 264.02 2018-07-01 00:00:00.000 1 NaN 2018-06-01 00:00:00.000
3 Réponses :
Ce qui suit devrait fonctionner:
df = df.iloc[::-1].reset_index(drop=True)
Résultat:
part price date 0 1 88.37 2018-07-01 1 3 264.02 2018-07-01 2 1 88.37 2018-08-01 3 3 264.02 2018-08-01 4 1 88.37 2018-09-01 5 3 212.70 2018-09-01 6 1 67.32 2018-10-01 7 3 167.34 2018-10-01 8 1 67.32 2018-11-01 9 3 167.34 2018-11-01 10 1 67.32 2018-12-01 11 3 99.16 2018-12-01
Un peu plus de détails:
'price'
par une colonne remplie à terme par groupe Si vous voulez le df
dans l'ordre que vous avez montré, vous pouvez retourner le dataframe:
df.loc[lambda df: df.groupby('part')['price'].transform(np.any)]\ .sort_values('date')\ .assign(price=lambda df: df.groupby('part')['price'].ffill())\ .dropna()\ .reset_index(drop=True)
Marche parfaitement. Merci.
Je pense que vous devez utiliser bfill plutôt que remplir ici:
In [14]: df = df.dropna(subset=['price']) In [15]: df Out[15]: part price date 0 1 67.32 2018-12-01 00:00:00.000 2 3 99.16 2018-12-01 00:00:00.000 3 1 67.32 2018-11-01 00:00:00.000 5 3 167.34 2018-11-01 00:00:00.000 6 1 67.32 2018-10-01 00:00:00.000 8 3 167.34 2018-10-01 00:00:00.000 9 1 88.37 2018-09-01 00:00:00.000 11 3 212.70 2018-09-01 00:00:00.000 12 1 88.37 2018-08-01 00:00:00.000 14 3 264.02 2018-08-01 00:00:00.000 15 1 88.37 2018-07-01 00:00:00.000 17 3 264.02 2018-07-01 00:00:00.000
Mettez donc à jour la colonne de prix:
In [12]: df['price'] = df.groupby('part')['price'].bfill() In [13]: df Out[13]: part price date 0 1 67.32 2018-12-01 00:00:00.000 1 2 NaN 2018-12-01 00:00:00.000 2 3 99.16 2018-12-01 00:00:00.000 3 1 67.32 2018-11-01 00:00:00.000 4 2 NaN 2018-11-01 00:00:00.000 5 3 167.34 2018-11-01 00:00:00.000 6 1 67.32 2018-10-01 00:00:00.000 7 2 NaN 2018-10-01 00:00:00.000 8 3 167.34 2018-10-01 00:00:00.000 9 1 88.37 2018-09-01 00:00:00.000 10 2 NaN 2018-09-01 00:00:00.000 11 3 212.70 2018-09-01 00:00:00.000 12 1 88.37 2018-08-01 00:00:00.000 13 2 NaN 2018-08-01 00:00:00.000 14 3 264.02 2018-08-01 00:00:00.000 15 1 88.37 2018-07-01 00:00:00.000 16 2 NaN 2018-07-01 00:00:00.000 17 3 264.02 2018-07-01 00:00:00.000 18 1 NaN 2018-06-01 00:00:00.000
Vous pouvez maintenant supprimer ceux avec un prix NaN:
In [11]: df.groupby('part')['price'].bfill() Out[11]: 0 67.32 1 NaN 2 99.16 3 67.32 4 NaN 5 167.34 6 67.32 7 NaN 8 167.34 9 88.37 10 NaN 11 212.70 12 88.37 13 NaN 14 264.02 15 88.37 16 NaN 17 264.02 18 NaN Name: price, dtype: float64
Avec vos données dans un dataframe (df) comme indiqué ci-dessus dans votre question, vous pouvez utiliser ce qui suit pour obtenir votre résultat:
part 1 3 date 2018-12-01 67.32 99.16 2018-11-01 67.32 167.34 2018-10-01 67.32 167.34 2018-09-01 88.37 212.70 2018-08-01 88.37 264.02 2018-07-01 88.37 264.02
Dans mon cas, votre réponse est dans un tableau croisé dynamique toutefois.
df = df.pivot_table('price', index='date', columns ='part').fillna(method='ffill') df.dropna().sort_index(ascending=False)