2 votes

Pandas : Définir les valeurs de toutes les lignes qui se trouvent entre deux lignes d'un cadre de données ?

Disons que nous avons un cadre de données pandas comme ci-dessous :

df = pd.DataFrame({"Basis": [300, 1500, 400, 260, 50,-10],"Weights":[0,-1,0,0,0,0]})
print(df)

   Basis  Weights
0    300        0
1   1500       -1
2    400        0
3    260        0
4     50        0
5    -10        0

J'ai donc trouvé comment définir la valeur de la colonne X de la ligne X en fonction des valeurs d'une autre colonne de cette même ligne. Ainsi, dans ce cadre de données, je peux définir tous les poids à -1 lorsque Basis > 1000.

df.loc[df['Basis'] > 1000, 'Weights'] = -1

Ce que je veux pouvoir faire est : dans un grand df de ce format, prendre toutes les lignes entre les deux une ligne où le poids est de -1 et une ligne ultérieure où la base <= 0 et dont la valeur du poids est fixée à -1 (donc, dans le cas de l'image, je veux fixer la valeur du poids des lignes 1 à 4 à -1, et je dois trouver comment le faire sans passer par toute la trame de données (je dois travailler avec un très grand ensemble de données).

Le résultat souhaité serait :

   Basis  Weights
0    300        0
1   1500       -1
2    400       -1
3    260       -1
4     50       -1
5    -10        0

Existe-t-il une manière élégante de faire cela qui évite de boucler sur l'ensemble de la base de données ? Par exemple, un moyen rapide d'implémenter la condition que le poids est égal au poids précédent si la base >=0.

0voto

mozway Points 233

Si vous n'avez que des valeurs >0 ou -1 dans les Poids, vous pouvez constituer des groupes à partir d'une Base négative et obtenir les résultats suivants cummin Poids :

group = df['Basis'].lt(0).cumsum()
df['Weights'] = df.groupby(group)['Weights'].cummin()

Si vous avez des valeurs arbitraires, c'est un peu plus complexe, vous devez d'abord masquer les valeurs non -1, ffill par groupe, puis rétablir les autres valeurs :

group = df['Basis'].lt(0).cumsum()
df['Weights'] = (df['Weights']
                 .where(df['Weights'].eq(-1))
                 .groupby(group).ffill()
                 .fillna(df['Weights'], downcast='infer')
                )

sortie :

   Basis  Weights
0    300        0
1   1500       -1
2    400       -1
3    260       -1
4     50       -1
5    -10        0

0voto

Mortz Points 677

Vous pouvez remplacer le 0 s avec nan et ensuite fillna -

df.loc[(df['Basis'] > 0) & (df['Weights'] >= 0), 'Weights'] = np.nan
df = df.fillna(method='ffill').fillna(0) 

Sortie

   Basis  Weights
0    300      0.0
1   1500     -1.0
2    400     -1.0
3    260     -1.0
4     50     -1.0
5    -10      0.0

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X