2017-07-21 1 views
1

Je bricolé des codes laids pour faire face à cela, mais voulait trouver un moyen pythonique:pandas géants avec des conditions

df = pd.DataFrame({'signal':[1,0,0,1,0,0,0,0,1,0,0,1,0,0],'product':['A','A','A','A','A','A','A','B','B','B','B','B','B','B'],'price':[1,2,3,4,5,6,7,1,2,3,4,5,6,7],'price_B':[1,1,1,4,4,4,4,0,2,2,2,5,5,5,]}) 

Je veux créer la colonne « Price_B ». Price_B est égal à Price si «signal» est 1. Price_B est égal au prix de la ligne précédente si le signal est 0. Si le sous-groupe commence par un «signal» 0, alors «price_B» sera maintenu à 0 jusqu'à ' signal » tourne 1.

Voici ce que je l'ai écrit:

dfb = df.groupby('product').get_group('B') 
for i in dfb.index: 
    if dfb.loc[i, 'signal'] == 1: 
     dfb.loc[i, 'test'] = dfb.loc[i, 'price'] 
    else: 
     try: 
      dfb.loc[i, 'test'] = dfb.loc[i - 1, 'test'] 
     except KeyError: 
      dfb.loc[i, 'test'] = 0 

Je sais que ces codes ne sont pas légales. Quelqu'un peut-il aider?

+0

Votre code dans la boucle 'for' n'est pas correctement indenté. – IanS

+0

oh oui. Tout juste mis à jour la boucle for –

+0

Utilisez .loc() Liste de la compréhension comme dans ma réponse ci-dessous – 2Obe

Répondre

1

J'utilise pd.Series.where pour annuler les données où le signal n'est pas 1. Ensuite, avancez et remplissez na.

def f(d): 
    dtype = d.price.dtype 
    p = d.price.where(d.signal.eq(1)) 
    return p.ffill().fillna(0).astype(dtype) 

df.assign(price_B=df.groupby('product', group_keys=False).apply(f)) 

    price price_B product signal 
0  1  1  A  1 
1  2  1  A  0 
2  3  1  A  0 
3  4  4  A  1 
4  5  4  A  0 
5  6  4  A  0 
6  7  4  A  0 
7  1  0  B  0 
8  2  2  B  1 
9  3  2  B  0 
10  4  2  B  0 
11  5  5  B  1 
12  6  5  B  0 
13  7  5  B  0 
+0

Salut, je me demandais comment ajouter un argument dans la fonction f (d) et l'appliquer à df? Maintenant, f (d) ne cible que la colonne ['price'], mais je voulais la rendre dynamique et laisser la fonction cibler d'autres colonnes comme ['price2'] –

0
df["price_B"]=[df.loc[i-1,"price_B"] if df.loc[i,"signal"]==0 else df.loc[i,"price"] for i in range(len(df["price"]))] 

print(df) 

    price price_B product signal 
0  1  1  A  1 
1  2  1  A  0 
2  3  1  A  0 
3  4  4  A  1 
4  5  4  A  0 
5  6  4  A  0 
6  7  4  A  0 
7  1  4  B  0 
8  2  2  B  1 
9  3  2  B  0 
10  4  2  B  0 
11  5  5  B  1 
12  6  5  B  0 
13  7  5  B  0