2017-06-09 4 views
1

I ont une .groupby de trame de données() .cumsum(), avec un trame de données comme suit:Grouper par .cumsum() vide si la colonne additionnée est égale à zéro?

Col_A Col_B Col_C 
1 A 0    
2 A 1  1  
3 A 1  2  
4 A 1  3  
5 B 0  0  
6 B 1  1  
7 B 0    
8 B 1  2  
9 C 1  1  
10 C 1  2  
11 C 1  3  
12 C 0   

La somme des Col_B est df.groupby(['Col_A'])['Col_B'].cumsum(). Cependant, lorsque Col_B == 0, le .cumsum() est vide. Comment puis-je enregistrer le .cumsum() même lorsque Col_B est vide?

Le dataframe résultant devrait ressembler à:

 Col_A Col_B Col_C 
    1 A 0  0  
    2 A 1  1  
    3 A 1  2  
    4 A 1  3  
    5 B 0  0  
    6 B 1  1  
    7 B 0  1  
    8 B 1  2  
    9 C 1  1  
    10 C 1  2  
    11 C 1  3  
    12 C 0  3  

Répondre

1

Je pense que vous avez besoin premier filtre par boolean indexing ou query:

df['Col_C'] = df[df['Col_B'] != 0].groupby(['Col_A'])['Col_B'].cumsum() 
print (df) 
    Col_A Col_B Col_C 
1  A  0 NaN 
2  A  1 1.0 
3  A  1 2.0 
4  A  1 3.0 
5  B  0 NaN 
6  B  1 1.0 
7  B  0 NaN 
8  B  1 2.0 
9  C  1 1.0 
10  C  1 2.0 
11  C  1 3.0 
12  C  0 NaN 

Ou:

df['Col_C'] = df.query('Col_B != 0').groupby(['Col_A'])['Col_B'].cumsum() 
print (df) 
    Col_A Col_B Col_C 
1  A  0 NaN 
2  A  1 1.0 
3  A  1 2.0 
4  A  1 3.0 
5  B  0 NaN 
6  B  1 1.0 
7  B  0 NaN 
8  B  1 2.0 
9  C  1 1.0 
10  C  1 2.0 
11  C  1 3.0 
12  C  0 NaN 

Et enfin remplacer NaN s par ffill (fillna avec la méthode = 'ffill'). Mais obtenir les premières valeurs encore NaN s, qui sont remplacés par fillna et dernière colonne de conversion à int:

df['Col_C'] = df['Col_C'].ffill().fillna(0).astype(int) 
print (df) 
    Col_A Col_B Col_C 
1  A  0  0 
2  A  1  1 
3  A  1  2 
4  A  1  3 
5  B  0  3 
6  B  1  1 
7  B  0  1 
8  B  1  2 
9  C  1  1 
10  C  1  2 
11  C  1  3 
12  C  0  3 
+0

Cette solution est correcte mis en œuvre. J'ai eu une idée que .ffill() après .groupby() était probablement correct, et c'était le cas. Merci! –

+1

Glad peut aider, bon week-end! – jezrael

1

Avoir une colonne de 0s n'est pas la même chose que d'avoir une colonne complètement vide. Si vous avez des NA dans une colonne, le .cumsum() pour cette colonne devrait en fait être NA (ou 'vide' comme vous le dites). Vous pouvez vérifier si la colonne entière est NA et définir la valeur en conséquence.

Documentation:

DataFrame.cumsum(axis=None, skipna=True, *args, **kwargs) 
Return cumulative sum over requested axis. 

skipna : boolean, default True 
Exclude NA/null values. If an entire row/column is NA, the result will be NA