Je fais probablement quelque chose de très stupide, mais je suis perplexe.
J'ai un cadre de données et je souhaite remplacer les valeurs d'une colonne donnée dépassant une valeur égale à zéro. J'avais pensé que c'était un moyen d'y parvenir:
df[df.my_channel > 20000].my_channel = 0
Si je copie le canal dans un nouveau cadre de données, c'est simple:
df2 = df.my_channel
df2[df2 > 20000] = 0
cela fait exactement ce que je veux, mais ne semble pas fonctionner avec le canal dans le cadre de données d'origine.
.ix
indexeur fonctionne correctement pour pandas version antérieure à 0.20.0, mais depuis pandas 0.20.0, l'indicateur .ix
est obsolète , vous devriez donc éviter de l'utiliser. A la place, vous pouvez utiliser les indexeurs .loc
ou iloc
. Vous pouvez résoudre ce problème en:
mask = df.my_channel > 20000
column_name = 'my_channel'
df.loc[mask, column_name] = 0
Ou, en une ligne,
df.loc[df.my_channel > 20000, 'my_channel'] = 0
mask
vous aide à sélectionner les lignes dans lesquelles df.my_channel > 20000
est True
, tandis que df.loc[mask, column_name] = 0
définit la valeur 0 sur les lignes sélectionnées où mask
est dans la colonne dont le nom est column_name
.
Mise à jour: Dans ce cas, vous devez utiliser loc
car si vous utilisez iloc
, vous obtiendrez un NotImplementedError
vous indiquant que iLocation L'indexation booléenne basée sur un type entier n'est pas disponible .
Essayer
df.loc[df.my_channel > 20000, 'my_channel'] = 0
Remarque: Depuis la v0.20.0, ix
est obsolète en faveur de loc
/iloc
.
La fonction np.where
fonctionne comme suit:
df['X'] = np.where(df['Y']>=50, 'yes', 'no')
Dans votre cas, vous voudriez:
import numpy as np
df['my_channel'] = np.where(df.my_channel > 20000, 0, df.my_channel)
La raison pour laquelle votre image de données d'origine ne met pas à jour est parce que indexé en chaîne peut vous amener à modifier une copie plutôt qu'une vue de votre image de données. Les docs donnent ce conseil:
Lorsque vous définissez des valeurs dans un objet pandas, vous devez éviter ce que l'on appelle l'indexation chaînée.
Vous avez quelques alternatives: -
loc
+ indexation booléenneloc
peut être utilisé pour définir des valeurs et prend en charge les masques booléens:
_df.loc[df['my_channel'] > 20000, 'my_channel'] = 0
_
mask
+ indexation booléenneVous pouvez affecter à votre série:
_df['my_channel'] = df['my_channel'].mask(df['my_channel'] > 20000, 0)
_
Ou vous pouvez mettre à jour votre série sur place:
_df['my_channel'].mask(df['my_channel'] > 20000, 0, inplace=True)
_
np.where
+ indexation booléenneVous pouvez utiliser NumPy en attribuant votre série d'origine lorsque votre condition est et non satisfait; Cependant, les deux premières solutions sont plus propres puisqu'elles ne modifient explicitement que les valeurs spécifiées.
_df['my_channel'] = np.where(df['my_channel'] > 20000, 0, df['my_channel'])
_
Essaye ça:
df.my_channel = df.my_channel.where(df.my_channel <= 20000, other= 0)
ou
df.my_channel = df.my_channel.mask(df.my_channel > 20000, other= 0)
J'utiliserais la fonction lambda
sur un Series
d'un DataFrame
comme ceci:
f = lambda x: 0 if x>100 else 1
df['my_column'] = df['my_column'].map(f)
Je n’affirme pas que c’est un moyen efficace, mais cela fonctionne bien.