我的数据集:
*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
只有两组。但我想要消极组,然后是积极组,然后是消极组……而且每个组都是独立的。
当您对特定列进行分组时,pandas 会对该组的唯一值进行分组;在您的情况下,只有两个基于标志的组:True 组和 False 组。当您对 groupby 对象应用总和时,您会得到每个组的总和。分组后检查的一种好方法是使用 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 方法使用的函数,但是我们需要使用 if 语句来检查该元素是否是列的最后一个值,而不是 try ,除了 block 。
我是一名优秀的程序员,十分优秀!