5
votes

Comment créer une somme de colonnes dans Pandas basée sur une condition de plusieurs colonnes?

J'essaye de faire la somme de deux colonnes du DataFrame pour créer une troisième colonne où la valeur de la troisième colonne est égale à la somme des éléments positifs des autres colonnes. J'ai essayé ce qui suit et je viens de recevoir une colonne de valeurs NaN

df = pd.DataFrame(np.array([[-1, 2], [-2, 2], [1, -3], [1, -4], [ -2 , -2]]),
                   columns=['a', 'b'])

df['Sum of Positives'] = 0

df['Sum of Positives'] = df.loc[df.a > 0 ,'a'] +df.loc[df.b >0 , 'b']

Trame de données:

entrez la description de l'image ici


5 commentaires

production attendue?


df ['Somme des positifs'] = [2, 2, 1, 1, 0]


Et comment les avez-vous calculés? Je ne sais toujours pas comment obtenir [2, 2, 0, 0, 0]


Désolé, je l'ai mal inséré, j'ai modifié mon commentaire pour refléter ce qu'il devrait être


Compris! Merci ;)


5 Réponses :


2
votes

Vous pouvez utiliser appliquer et sous-ensemble sur les points positifs:

df['Sum of Positives']  = df.apply(lambda x:sum(x[x>0]),axis=1)

    a   b   Sum of Positives
0   -1  2   2
1   -2  2   2
2    1 -3   1
3    1 -4   1
4   -2 -2   0


1 commentaires

apply sera beaucoup plus lent que la solution de mask par exemple



4
votes

Vous pouvez utiliser df.mask ici et remplir une valeur inférieure à 0, c'est-à-dire une valeur négative avec 0 et faire df.sum sur l'axe 1.

m = np.ma.array(df.values, mask=df.values<0, fill_value=0)
df['sum of pos'] = m.filled().sum(axis=1)

Peu de hacks NumPy sont aussi utiles ici.

  • Utilisation de np.copyto

    df['sum of pos'] = np.clip(df.values, 0, None).sum(axis=1)
    
  • Utilisation de np.where

    df['sum of pos'] = np.where(df.values<0, 0, df.values).sum(axis=1)
    
  • Utilisation de np.clip

    t = np.copy(df.values)
    np.copyto(t, 0, where=df.values<0)
    df['sum of pos'] = t.sum(axis=1)
    
  • Utilisation de np.ma.array

    df['sum of pos'] = df.mask(df<0, 0).sum(axis=1)
    
       a  b  sum of pos
    0 -1  2           2
    1 -2  2           2
    2  1 -3           1
    3  1 -4           1
    4 -2 -2           0
    


0 commentaires

0
votes

Vous pouvez supprimer les valeurs négatives avec clip .

>>> df['Sum of Positives'] = df.clip(lower=0).sum(axis=1)
>>> df
   a  b  Sum of Positives
0 -1  2                 2
1 -2  2                 2
2  1 -3                 1
3  1 -4                 1
4 -2 -2                 0


0 commentaires

0
votes

Cela se produit parce que df.loc [condition, col] filtre les lignes qui ne correspondent pas à la condition, de sorte que vous finissez par additionner les valeurs positives avec des vides. Ce que vous voudriez ici, c'est remplacer dans vos colonnes les valeurs négatives par zéro et la somme des colonnes:

df['Sum of Positives'] = df.applymap(lambda x: max(x,0)).sum(axis=1)


0 commentaires

1
votes

Essayons le clip

df.clip(lower=0).sum(1)
Out[19]: 
0    2
1    2
2    1
3    1
4    0
dtype: int64


0 commentaires