2017-07-21 218 views
1

改造我修修補補一些醜陋的代碼來解決這個問題,但希望找到一個Python的方式:熊貓橫行的條件

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

我要創建「Price_B」列。對於每個「產品」子組,如果信號爲1,則Price_B等於Price。如果信號爲0,則Price_B等於前一行的價格。如果子組以「0」信號開始,則'price_B'將保持爲0直到'信號」變成1

下面是我寫的:

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 

我知道這些代碼是不合法的。有人可以幫忙嗎?

+0

您在for循環中的代碼沒有正確縮進。 – IanS

+0

哦,是的。剛剛更新了for循環 –

+0

使用.loc()列表理解喜歡在我的回答下面 – 2Obe

回答

1

我會使用pd.Series.where以抵消數據,其中信號不1。然後向前填充並填充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

嗨,我想知道如何在f(d)函數中添加一個參數並將其應用於df? 現在f(d)只針對['price']列,但我想讓它變爲動態並讓函數定位其他列,如['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