我的数据集:
*195 -1.888996
196 -4.402077*
197 0.171813
198 2.182845
199 2.349494
200 2.239476
*201 -0.340724
202 -3.056798
203 -4.815240
204 -8.040102
205 -9.316368
206 -9.410789
207 -7.844607
208 -4.791272
209 -4.273477
210 -1.660889
211 -0.931744
212 -1.163933
213 -0.452218*
214 1.580649
215 4.331421
216 6.101737
我希望将负数组和正数组等数据分组。我在下面试过。
df['flag']=df.MACD.apply(lambda x:True if x>0 else False)
df.MACD.groupby(df.flag).sum()
flag
False -738.959009
True 873.042392
Name: MACD, dtype: float64
只有两组。但我想要消极群体,然后是积极群体,然后是消极群体...而且每个群体都是独立的。
答案 0 :(得分:0)
当您对特定列执行groupby时,pandas会创建该组的唯一值组;在这种情况下,只有两组基于标志,True组和False组。当您在groupby对象上应用sum时,您将获得每个组的总和。 分组后检查的一个好方法是使用for循环检查,例如说
gpd=df.MACD.groupby(df.flag)
for label,grp in gpd:
print(grp)
从你的问题来看,你看起来想要连续的正数和负数的总和,这是一种方法。
import pandas as pd
import numpy as np
df=pd.DataFrame()
df['a']=[-1,-2,1,1,-2,-2,2,3,1]
df['positives']=df.where(df['a']>0).apply(np.cumsum)
df['negatives']=df.where(df['a']<0).apply(np.cumsum)
应该导致
a positives negatives
0 -1 NaN -1.0
1 -2 NaN -3.0
2 1 1.0 NaN
3 1 2.0 NaN
4 -2 NaN -5.0
5 -2 NaN -7.0
6 2 4.0 NaN
7 3 7.0 NaN
8 1 8.0 NaN
因此您所需的正值在指数3,8中,负数在指数1,5中 如果您还想删除这些连续元素并自动报告这些位置,请考虑使用类似df.shift
的内容df['flag']=df.a.apply(lambda x:True if x>0 else False) #adds a flags like your example.
df['compare']=df['flag']==df['flag'].shift(-1)
df[df['compare']==False]
应该导致
a positives negatives flag compare
1 -2 NaN -3.0 False False
3 1 2.0 NaN True False
5 -2 NaN -7.0 False False
8 1 8.0 NaN True False
正面和负面是连续正负段的连续总和。
更新:更新到解决方案(来自OP的评论) 所需要的是独立正面和负面部分的集合。 一种方法是定义一个简单的函数,如下面的
def signed_agg(pd_col):
val=0
sgn=None
col_iter=pd_col.iteritems()
try:
while True:
x=col_iter.next()[1]
if not sgn:
sgn=np.sign(x)
if not np.sign(x)==sgn:
yield val
val=x
sgn=np.sign(x)
else:
val+=x
tmp,sgn=(sgn,np.nan)
yield sgn
sgn=tmp
except StopIteration:
yield val
将列传递给此函数并创建可与原始
合并的数据框pd.DataFrame(signed_agg(df['a']),columns=['signed_agg'])
产量
signed_agg
0 NaN
1 NaN
2 -3.0
3 NaN
4 2.0
5 NaN
6 -4.0
7 NaN
8 NaN
9 6.0
也可以用类似的方式编写一个函数,可以由apply方法使用,但是然后代替try,除了block之外,我们需要使用if语句检查元素是否是列的最后一个值。