以下示例:
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],'price2':[1,2,1,2,1,2,1,2,1,2,1,2,1,2]})
我有一个功能" fill_price"创建一个新列' Price_B'基于' signal'和'价格'。对于每个产品'子群,Price_B等于价格,如果'信号'如果信号为0,则Price_B等于前一行的Price_B。如果子组以0'信号开始,那么' price_B'将保持在0,直到' signal'转1。
目前我有:
def fill_price(df, signal,price_A):
p = df[price_A].where(df[signal] == 1)
return p.ffill().fillna(0).astype(df[price_A].dtype)
然后使用:
应用df['Price_B'] = fill_price(df,'signal','price')
但是,我想使用df.groupby(' product')。apply()将此fill_price函数应用于"产品'的两个子集。列分开,也适用于“价格”和“价格”。和' price2'列。有人可以帮忙吗?
我基本上想做:
df.groupby('product',groupby_keys=False).apply(fill_price, 'signal','price2')
答案 0 :(得分:1)
IIUC,您可以使用以下语法:
df['Price_B'] = df.groupby('product').apply(lambda x: fill_price(x,'signal','price2')).reset_index(level=0, drop=True)
输出:
price price2 product signal Price_B
0 1 1 A 1 1
1 2 2 A 0 1
2 3 1 A 0 1
3 4 2 A 1 2
4 5 1 A 0 2
5 6 2 A 0 2
6 7 1 A 0 2
7 1 2 B 0 0
8 2 1 B 1 1
9 3 2 B 0 1
10 4 1 B 0 1
11 5 2 B 1 2
12 6 1 B 0 2
13 7 2 B 0 2
如果没有额外的功能,你可以写得更简单。
df['Price_B'] = (df.groupby('product',as_index=False)
.apply(lambda x: x['price2'].where(x.signal==1).ffill().fillna(0))
.reset_index(level=0, drop=True))