web-dev-qa-db-fra.com

si d'autre fonction dans les données de pandas

J'essaie d'appliquer une condition if sur une image, mais il me manque quelque chose (erreur: la valeur de vérité d'une série est ambiguë. Utilisez a.empty, a.bool (), a.item (), a. any () ou a.all ().)

raw_data = {'age1': [23,45,21],'age2': [10,20,50]}
df = pd.DataFrame(raw_data, columns = ['age1','age2'])

def my_fun (var1,var2,var3):
if (df[var1]-df[var2])>0 :
    df[var3]=df[var1]-df[var2]
else:
    df[var3]=0
print(df[var3])

my_fun('age1','age2','diff')
6
progster

Vous pouvez utiliser numpy.where :

def my_fun (var1,var2,var3):
    df[var3]= np.where((df[var1]-df[var2])>0, df[var1]-df[var2], 0)
    return df

df1 = my_fun('age1','age2','diff')
print (df1)
   age1  age2  diff
0    23    10    13
1    45    20    25
2    21    50     0

L'erreur est mieux expliquer ici .

Solution plus lente avec apply, où besoin axis=1 pour le traitement des données par lignes:

def my_fun(x, var1, var2, var3):
    print (x)
    if (x[var1]-x[var2])>0 :
        x[var3]=x[var1]-x[var2]
    else:
        x[var3]=0
    return x    

print (df.apply(lambda x: my_fun(x, 'age1', 'age2','diff'), axis=1))
   age1  age2  diff
0    23    10    13
1    45    20    25
2    21    50     0

Il est également possible d'utiliser loc, mais parfois, les données peuvent être écrasées:

def my_fun(x, var1, var2, var3):
    print (x)
    mask = (x[var1]-x[var2])>0
    x.loc[mask, var3] = x[var1]-x[var2]
    x.loc[~mask, var3] = 0

    return x    

print (my_fun(df, 'age1', 'age2','diff'))
   age1  age2  diff
0    23    10  13.0
1    45    20  25.0
2    21    50   0.0
10
jezrael

Vous pouvez utiliser pandas.Series.where

df.assign(age3=(df.age1 - df.age2).where(df.age1 > df.age2, 0))

   age1  age2  age3
0    23    10    13
1    45    20    25
2    21    50     0

Vous pouvez envelopper ceci dans une fonction

def my_fun(v1, v2):
    return v1.sub(v2).where(v1 > v2, 0)

df.assign(age3=my_fun(df.age1, df.age2))

   age1  age2  age3
0    23    10    13
1    45    20    25
2    21    50     0
4
piRSquared

Il existe un autre moyen sans np.where ou pd.Series.where. Je ne dis pas que c'est mieux, mais après avoir essayé d'adapter cette solution à un problème épineux aujourd'hui, il a été difficile de trouver la syntaxe pour where pas si intuitif. En fin de compte, je ne sais pas si cela aurait été possible avec où, mais la méthode suivante vous a permis de jeter un coup d’œil sur le sous-ensemble avant de le modifier. Cela fonctionne bien sûr également pour le PO. 

Vous définissez délibérément une valeur sur une tranche d'une trame de données, car les Pandas vous avertissent si souvent de ne pas le faire. 

Ceci réponse vous indique la bonne méthode pour le faire.

Ce qui suit vous donne une tranche:

df.loc[df['age1'] - df['age2'] > 0]

..qui ressemble à:

   age1  age2
0    23    10
1    45    20

Ajoutez une colonne supplémentaire à la structure de données d'origine pour les valeurs que vous souhaitez conserver après la modification de la tranche:

df['diff'] = 0

Maintenant modifiez la tranche:

df.loc[df['age1'] - df['age2'] > 0, 'diff'] = df['age1'] - df['age2']

..et le résultat:

   age1  age2  diff
0    23    10    13
1    45    20    25
2    21    50     0
1
cardamom