大熊猫据帧申请使用额外的参数

大熊猫据帧申请使用额外的参数

问题描述:

与下面的例子:大熊猫据帧申请使用额外的参数

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”基于“信号”和“价格”。对于每个“产品”子组,如果信号为1,则Price_B等于Price。如果信号为0,则Price_B等于前一行的Price_B。如果子组以“0”信号开始,则'price_B'将保持为0直到'信号”变成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。( '产品')申请( )将这个fill_price函数分别应用于“产品”列的两个子集,并将其同时应用于“价格”和“价格2'栏。有人可以帮忙吗?

我基本上要做到:

df.groupby('product',groupby_keys=False).apply(fill_price, 'signal','price2') 
+0

这是行吗? 'df.groupby('product')。apply(lambda x:fill_price(x,'signal','price'))' –

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 

你可以写这么多simplier没有额外功能。

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)) 
+0

它有效。我有点困惑,因为1.为什么我们在最后重置索引2.函数适用于数据框,但在lambda函数中,我们通过它提供行? 谢谢 –

+0

这是你的函数建立的方式,你正在返回一个带有索引的数据框,然后groupby正在为该组添加一个新的索引。是的,你的函数接受一个数据帧作为第一个参数,在lambda函数中,我们只是将一些数据帧的“分组”行传递给你的函数,它返回一个数据帧,然后我们将外部索引去掉,让Pandas对齐您的原始数据帧与基于原始索引的已修改数据帧。 –

+0

@PrintableBao请参阅更新我在纯lambda函数中重写的地方,而不使用额外的函数调用。 –