这是这post的延伸.
我的数据帧是:
import pandas as pd
df = pd.DataFrame(
{
'a': [
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b',
],
'b': [
-20, 20, 20, 20,-70, -70, 10, -1000, -10, 100, 100,
-11, -100, -1, -1, -100, 100, 1, 90, -1, -2, 1000, 900
],
'c': [
'f', 'f', 'f', 'f', 'f', 'x', 'x', 'x', 'y', 'y', 'y', 'a',
'k', 'k', 'k', 'k', 'k', 't', 't', 't', 't', 's', 'e',
],
}
)
这就是我想要的输出.我想要一个有六列的数据帧:
a direction length sum start end
a -1 2 -1010 x y
a 1 3 60 f f
b -1 4 -202 k k
b 1 3 191 k t
我想要获得列b
中针对列a
中的每个组的最大正负条纹,并在此之后将列b
的值相加.这个问题已经解决了here个.在上面注明的帖子中,我更详细地解释了这个问题.
现在我想补充的是:在找到b
中最长的正负条纹的总和后,我需要这些条纹第c
列的起始值和结束值.
在这张图中,我突出显示了拥有最长连胜纪录的组:
我试过的是:
df['sign'] = np.sign(df.b)
group = df['sign'].ne(df['sign'].shift()).cumsum()
out = (df
.assign(direction=np.sign(df['b']))
.groupby(['a', 'direction', group], as_index=False)
.agg(length=('b', 'count'),
sum=('b', 'sum'))
.sort_values(by='sum', key=abs, ascending=False)
.loc[lambda d: d.groupby(['a', 'direction'])['length'].idxmax(),
['a','direction', 'length', 'sum']]
)
df['streak'] = df['sign'].ne(df['sign'].shift()).cumsum()
df['length'] = df.groupby('streak')['b'].transform('size')
df['sum'] = df.groupby('streak', as_index=False)['b'].transform(sum)
dfm = df.merge(out, on=['a', 'length', 'sum'], how='inner')
它正在接近,但感觉这不是做这件事的方式.