2013-06-29 3 views
0

Supposons que je crée un DataFrame pandas avec deux colonnes, dont l'une contient des nombres et l'autre des lettres. Comme ceci:Les pandas obtiennent la dernière valeur de la colonne x lorsque la colonne y est égale à z

import pandas as pd 
from pprint import pprint 

df = pd.DataFrame({'a': [1,2,3,4,5,6], 'b': ['y','x','y','x','y', 'y']}) 
pprint(df) 

    a b 
0 1 y 
1 2 x 
2 3 y 
3 4 x 
4 5 y 
5 6 y 

disent Maintenant que je veux faire une troisième colonne (c) dont la valeur est égale à la dernière valeur de a quand b était égal à x. Dans les cas où une valeur de x n'a pas été rencontrée dans b encore, la valeur par défaut devrait c à 0.

La procédure devrait produire à peu près le résultat suivant:

last_a = 0 
c = [] 
for i,b in enumerate(df['b']): 
    if b == 'x': 
     last_a = df.iloc[i]['a'] 
    c += [last_a] 

df['c'] = c 
pprint(df) 


    a b c 
0 1 y 0 
1 2 x 2 
2 3 y 2 
3 4 x 4 
4 5 y 4 
5 6 y 4 

est-il un plus élégant moyen d'accomplir ceci avec ou sans pandas?

Répondre

2
In [140]: df = pd.DataFrame({'a': [1,2,3,4,5,6], 'b': ['y','x','y','x','y', 'y']}) 

In [141]: df 
Out[141]: 
    a b 
0 1 y 
1 2 x 
2 3 y 
3 4 x 
4 5 y 
5 6 y 

savoir où la colonne « b » == x, puis revenir à la valeur de cette colonne (pas l'emplacement); cette colonne est déjà la « une » colonne

In [142]: df['c'] = df.loc[df['b']=='x','a'].apply(lambda v: v if v < len(df) else np.nan) 

Remplissez le reste des valeurs vers l'avant, puis remplir les trous avec 0

In [143]: df['c'] = df['c'].ffill().fillna(0) 

In [144]: df 
Out[144]: 
    a b c 
0 1 y 0 
1 2 x 2 
2 3 y 2 
3 4 x 4 
4 5 y 4 
5 6 y 4 
Questions connexes