大熊猫据帧申请使用额外的参数
与下面的例子:大熊猫据帧申请使用额外的参数
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')
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))
它有效。我有点困惑,因为1.为什么我们在最后重置索引2.函数适用于数据框,但在lambda函数中,我们通过它提供行? 谢谢 –
这是你的函数建立的方式,你正在返回一个带有索引的数据框,然后groupby正在为该组添加一个新的索引。是的,你的函数接受一个数据帧作为第一个参数,在lambda函数中,我们只是将一些数据帧的“分组”行传递给你的函数,它返回一个数据帧,然后我们将外部索引去掉,让Pandas对齐您的原始数据帧与基于原始索引的已修改数据帧。 –
@PrintableBao请参阅更新我在纯lambda函数中重写的地方,而不使用额外的函数调用。 –
这是行吗? 'df.groupby('product')。apply(lambda x:fill_price(x,'signal','price'))' –