J'essaie de parcourir un cadre de données de pandas et de mettre à jour la valeur si la condition est remplie, mais j'obtiens une erreur.
for line, row in enumerate(df.itertuples(), 1):
if row.Qty:
if row.Qty == 1 and row.Price == 10:
row.Buy = 1
AttributeError: can't set attribute
Une première itération dans les pandas est possible, mais très lente, une autre solution vectorisée est utilisée.
Je pense que vous pouvez utiliser iterrows
si vous avez besoin d'itérer:
for idx, row in df.iterrows():
if df.loc[idx,'Qty'] == 1 and df.loc[idx,'Price'] == 10:
df.loc[idx,'Buy'] = 1
Mais il vaut mieux utiliser des solutions vectorisées - définissez la valeur avec un masque booléen avec loc
:
mask = (df['Qty'] == 1) & (df['Price'] == 10)
df.loc[mask, 'Buy'] = 1
Ou solution avec mask
:
df['Buy'] = df['Buy'].mask(mask, 1)
Ou si vous avez besoin de if...else
, utilisez numpy.where
:
df['Buy'] = np.where(mask, 1, 0)
Échantillons.
Définir les valeurs par conditions:
df = pd.DataFrame({'Buy': [100, 200, 50],
'Qty': [5, 1, 1],
'Name': ['Apple', 'pear', 'banana'],
'Price': [1, 10, 10]})
print (df)
Buy Name Price Qty
0 100 Apple 1 5
1 200 pear 10 1
2 50 banana 10 1
mask = (df['Qty'] == 1) & (df['Price'] == 10)
df['Buy'] = df['Buy'].mask(mask, 1)
print (df)
Buy Name Price Qty
0 100 Apple 1 5
1 1 pear 10 1
2 1 banana 10 1
df['Buy'] = np.where(mask, 1, 0)
print (df)
Buy Name Price Qty
0 0 Apple 1 5
1 1 pear 10 1
2 1 banana 10 1
Ok, si vous souhaitez définir des valeurs dans df
, vous devez suivre les valeurs index
.
Option 1
en utilisant itertuples
# keep in mind `row` is a named Tuple and cannot be edited
for line, row in enumerate(df.itertuples(), 1): # you don't need enumerate here, but doesn't hurt.
if row.Qty:
if row.Qty == 1 and row.Price == 10:
df.set_value(row.Index, 'Buy', 1)
Option 2
en utilisant iterrows
# keep in mind that `row` is a `pd.Series` and can be edited...
# ... but it is just a copy and won't reflect in `df`
for idx, row in df.iterrows():
if row.Qty:
if row.Qty == 1 and row.Price == 10:
df.set_value(idx, 'Buy', 1)
option 3
en utilisant la boucle droite avec get_value
for idx in df.index:
q = df.get_value(idx, 'Qty')
if q:
p = df.get_value(idx, 'Price')
if q == 1 and p == 10:
df.set_value(idx, 'Buy', 1)
la méthode pandas.DataFrame.set_value est obsolète à partir de 0.21.0 pd.DataFrame.set_value
Utilisez pandas.Dataframe.at
for index, row in df.iterrows():
if row.Qty and row.Qty == 1 and row.Price == 10:
df.at[index,'Buy'] = 1