2017-07-21 10 views
1

gebastelt ich einige hässliche Codes damit umgehen, aber wollte einen pythonic Weg, um herauszufinden:Pandas zeilenweise Transformation mit Bedingungen

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,]}) 

ich die ‚Price_B‘ Spalte erstellen möchten. Für jede Untergruppe 'Produkt' ist Price_B gleich Price, wenn 'Signal' 1 ist. Price_B ist gleich dem Preis der vorherigen Zeile, wenn das Signal 0 ist. Wenn die Untergruppe mit einem 0 'Signal' beginnt, wird 'price_B' auf 0 gehalten. ‚Signal schaltet 1.

Hier sind, was ich schrieb:

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 

ich weiß, dass diese Codes sind nicht legal. Kann jemand helfen?

+0

Ihr Code in der for-Schleife ist nicht richtig eingerückt. – IanS

+0

oh ja. Just updated die for-Schleife –

+0

Verwenden .loc() List Verständnis wie in meiner Antwort unter – 2Obe

Antwort

1

würde ich pd.Series.where verwenden, um Daten ungültig zu machen, wobei das Signal nicht 1 ist. Dann weiter füllen und füllen 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

Hallo, fragte ich mich, wie man ein Argument in der f (d) -Funktion hinzufügen und es auf df anwenden? Jetzt f (d) zielt nur auf ['Preis'] Spalte, aber ich wollte es dynamisch machen und lassen Sie die Funktion andere Spalten wie ['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 
Verwandte Themen