大熊猫有条件的行向变换

时间:2017-07-21 14:02:30

标签: python pandas lambda row slice

我修改了一些丑陋的代码来解决这个问题,但想找出一种pythonic方式:

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'柱。对于每个产品'子群,Price_B等于价格,如果'信号'如果信号为0,则Price_B等于前一行的价格。如果子组以0'信号开始,那么' price_B'将保持在0,直到' signal'转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

我知道这些代码不合法​​。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:2)

我使用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

答案 1 :(得分: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