2016-11-19 1 views
3

J'ai une trame de données de pandas géants qui ressemble à ceci (indice, Place):Python Colonne de retenue Valeur

0 California* 
1 LA 
2 San Diego 
3 Oakland 
4 Washington* 
5 Seattle 
6 Tacoma 

Les valeurs en place qui sont des états sont marqués d'un astérisque, donc je voudrais créer une nouvelle colonne et remplissez-la avec la valeur d'état. Je veux assigner la valeur pour l'état basé sur n'importe quelle rangée qui a un astérisque et puis le remplir pour toutes les rangées suivantes jusqu'à ce qu'une nouvelle rangée vienne avec une nouvelle valeur. Dans SAS, cela serait fait avec une déclaration de retenue, mais je ne sais pas comment cela fonctionne avec les pandas.

La sortie devrait être (indice, Place, État):

0 California* California 
1 LA   California 
2 San Diego California 
3 Oakland  California 
4 Washington* Washington 
5 Seattle  Washington 
6 Tacoma  Washington 

etc.

Qu'est-ce qu'un moyen simple et élégant d'aller à ce sujet?

Répondre

2

Vous pouvez utiliser Series.where avec un masque créé avec indexing with str et ffill:

print (df.col.str[-1] == '*') 
0  True 
1 False 
2 False 
3 False 
4  True 
5 False 
6 False 
Name: col, dtype: bool 

df['new'] = df.col.str[:-1].where(df.col.str[-1] == '*').ffill() 
print (df) 
      col   new 
0 California* California 
1   LA California 
2 San Diego California 
3  Oakland California 
4 Washington* Washington 
5  Seattle Washington 
6  Tacoma Washington 
1

Vous pouvez utiliser la méthode Series.str.extract() conjointement avec Series.ffill():

In [236]: df['State'] = df.Place.str.extract(r'([^\*]+)\*', expand=False).ffill() 

In [237]: df 
Out[237]: 
     Place  State 
0 California* California 
1   LA California 
2 San Diego California 
3  Oakland California 
4 Washington* Washington 
5  Seattle Washington 
6  Tacoma Washington 
0

réponse créative

df.iloc[:, 0].str.split('*').str[::-1] \ 
    .apply(pd.Series).replace('', np.nan).bfill(1).ffill() 

enter image description here


réponse sérieuse
utilise extract comme @MaxU. La différence est que j'utilise insert. Rien de bien meilleur, juste différent.

df.insert(df.shape[1], 'State', df.iloc[:, 0].str.extract('(.*)\*')) 
df = df.ffill() 

df 

enter image description here