3
votes

pandas groupby - fonction personnalisée

J'ai le dataframe suivant dans lequel j'utilise groupby et sum ():

col1 col2   
A   6.0
B   15.0
C   0.0

Il en résulte ce qui suit:

d = {'col1': ["A", "A", "A", "B", "B", "B", "C", "C","C"], 'col2': [1,2,3,4,5,6, np.nan, np.nan, np.nan]}

df = pd.DataFrame(data=d)

df.groupby("col1").sum()

Je veux que C affiche NaN au lieu de 0 car toutes les valeurs de C sont NaN. Comment puis-je accomplir cela? Apply () avec une fonction lambda? Toute aide serait appréciée.


1 commentaires

La logique est-elle NaN parce que chaque valeur est NaN ? Pour un groupe avec 1 2 NaN devez-vous retourner NaN ou 3?


3 Réponses :


3
votes

Utilisez ceci:

  col1  col2
0  AAA   6.0
1  BBB  15.0
2  CCC   NaN

Sans le apply () grâce à @piRSquared:

df.set_index('col1').sum(level=0,min_count=1).reset_index()

merci @Alollz: Si vous souhaitez renvoyer la somme des groupes contenant NaN et pas seulement NaNs

df.set_index('col1').sum(level=0, min_count=1).reset_index()

Sortie

df.groupby('col1').apply(pd.DataFrame.sum,skipna=False).reset_index(drop=True)
#Or --> df.groupby('col1',as_index=False).apply(pd.DataFrame.sum,skipna=False)


13 commentaires

sans apply ... df.set_index ('col1'). sum (level = 0, skipna = False) .reset_index ()


@piRSquared toujours une logique de génie. :) si vous voulez, vous pouvez poster une réponse et merci pour le vote positif. :)


Non. C'est trop semblable au vôtre dans l'esprit. Il appartient en tant que commentaire ici ou dans votre message. N'hésitez pas à l'ajouter si vous le souhaitez.


@piRSquared merci, appris que ce concept peut être utilisé pour de nombreuses opérations que j'utilise quotidiennement. Merci pour toutes vos réponses. :)


@piRSquared le seul problème ici est que lorsque A et B contiennent NaN, le résultat sera NaN


Ouais, je pense que cela pourrait être min_count = 1


@ALollz Je pense que vous avez raison. (-: Eh bien, selon que OP veut juste un nan pour faire exploser tout le groupe ou seulement si tout nan


@ALollz cela a plus de sens pour moi. n'hésitez pas à poster une réponse. :)


@ALollz ce n'est pas dommage de dire que je ne sais pas appliquer le nombre minimum de la bonne manière. :(


Ce dont j'ai besoin, c'est que si tout le groupe est NaN, alors la «somme» doit résulter en NaN. Juste pour info, le contexte réel ici est la réduction des paiements dus aux patients. Une valeur numérique indique qu'un paiement patient a été réduit à cette valeur. Un zéro indique que le paiement patient a été réduit à zéro. Un NaN indique qu'il n'y a pas de réduction et que le montant total est dû.


Ma même réponse mais avec min_count df.set_index ('col1'). Sum (level = 0, min_count = 1) .reset_index ()


@piRSquared aha ..! Merci. J'essayais df.set_index ('col1'). sum (level = 0, skipna = False, min_count = 1) .reset_index () : P


@ALollz merci beaucoup. Mis à jour votre suggestion aussi .. !!



1
votes

faire que l'appel à sum ait le paramètre skipna = False.

https: //pandas.pydata .org / pandas-docs / stable / reference / api / pandas.DataFrame.sum.html

ce lien devrait fournir la documentation dont vous avez besoin et j'espère que cela résoudra votre problème.


0 commentaires

2
votes

Merci à @piRSquared, @Alollz et @ anky_91:

Vous pouvez utiliser sans définir d'index et réinitialiser l'index:

  col1  col2
0    A   6.0
1    B  15.0
2    C   NaN

Sortie:

XXX


1 commentaires

Cela fonctionne parfaitement. Très intelligent. Je n'aurais pas pensé à vérifier les arguments sum (). Merci encore pour votre aide.