Python 按连续负值或正值拆分的时间序列上的累积和

Python 按连续负值或正值拆分的时间序列上的累积和,python,pandas,Python,Pandas,我的时间序列数据如下所示: date values 2017-05-01 1 2017-05-02 0.5 2017-05-03 -2 2017-05-04 -1 2017-05-05 -1.25 2017-05-06 0.5 2017-05-07 0.5 date values newfield 2017-05-01 1 1 | 2017-05-02

我的时间序列数据如下所示:

date        values
2017-05-01      1
2017-05-02      0.5
2017-05-03     -2
2017-05-04     -1
2017-05-05     -1.25
2017-05-06      0.5
2017-05-07      0.5
date        values   newfield
2017-05-01      1         1      |
2017-05-02      0.5       1.5    |
2017-05-03     -2        -2    |
2017-05-04     -1        -3    |
2017-05-05     -1.25     -4.25 |
2017-05-06      0.5       0.5    |
2017-05-07      0.5       1      |
我想添加一个字段,用于按趋势计算我的时间序列的累积和:连续正值之和,连续负值之和。 看起来像这样的东西:

date        values
2017-05-01      1
2017-05-02      0.5
2017-05-03     -2
2017-05-04     -1
2017-05-05     -1.25
2017-05-06      0.5
2017-05-07      0.5
date        values   newfield
2017-05-01      1         1      |
2017-05-02      0.5       1.5    |
2017-05-03     -2        -2    |
2017-05-04     -1        -3    |
2017-05-05     -1.25     -4.25 |
2017-05-06      0.5       0.5    |
2017-05-07      0.5       1      |
目前,我正在尝试使用shift,然后有条件,但这真的没有效率,我意识到这真的不是一个好方法

def pn(x, y):
if x < 0 and y < 0:
    return 1
if x > 0 and y > 0:
    return 1
else:
    return 0 

def consum(x,y,z):
if z == 0:
    return x
if y == 1:
    return x+y

test = pd.read_csv("./test.csv", sep=";")
test['temp'] = test.Value.shift(1)
test['temp2'] = test.apply(lambda row: pn(row['Value'], row['temp']), axis=1)
test['temp3'] = test.apply(lambda row: consum(row['Value'], row['temp'], row['temp2']), axis=1)

    Date        Value     temp  temp2   temp3
    2017-05-01   1       nan    0       1
    2017-05-02   0.5     1      1       1.5
    2017-05-03  -2       0      0      -2
    2017-05-04  -1      -2      1       nan
    2017-05-05  -1.25   -1      1       nan
    2017-05-06   0.5    -1.25   0       0.5
    2017-05-07   0.5     0.5    1       nan
def pn(x,y):
如果x<0且y<0:
返回1
如果x>0且y>0:
返回1
其他:
返回0
def消耗(x、y、z):
如果z==0:
返回x
如果y==1:
返回x+y
test=pd.read_csv(“./test.csv”,sep=“;”)
测试['temp']=测试值移位(1)
测试['temp2']=test.apply(lambda行:pn(行['Value'],行['temp']),轴=1)
测试['temp3']=test.apply(lambda行:consum(行['Value'],行['temp'],行['temp2']),轴=1)
日期值temp2 temp3
2017-05-01南0 1
2017-05-02   0.5     1      1       1.5
2017-05-03  -2       0      0      -2
2017-05-04-1-21南
2017-05-05-1.25-11楠
2017-05-06   0.5    -1.25   0       0.5
2017-05-07 0.50.5 1楠

从那以后我就迷路了。我可以继续转换我的值,并有很多if语句,但一定有更好的方法。

将0与正数相加,可以使用shift-compare-cumsum模式:

In [33]: sign = df["values"] >= 0

In [34]: df["vsum"] = df["values"].groupby((sign != sign.shift()).cumsum()).cumsum()

In [35]: df
Out[35]: 
         date  values  vsum
0  2017-05-01    1.00  1.00
1  2017-05-02    0.50  1.50
2  2017-05-03   -2.00 -2.00
3  2017-05-04   -1.00 -3.00
4  2017-05-05   -1.25 -4.25
5  2017-05-06    0.50  0.50
6  2017-05-07    0.50  1.00
这是因为
(sign!=sign.shift()).cumsum()为每个相邻组提供了一个新的编号:

In [36]: sign != sign.shift()
Out[36]: 
0     True
1    False
2     True
3    False
4    False
5     True
6    False
Name: values, dtype: bool

In [37]: (sign != sign.shift()).cumsum()
Out[37]: 
0    1
1    1
2    2
3    2
4    2
5    3
6    3
Name: values, dtype: int64
创建一个组:

g = np.sign(df['values']).diff().ne(0).cumsum()
g
输出:

0    1
1    1
2    2
3    2
4    2
5    3
6    3
Name: values, dtype: int64
   values
0    1.00
1    1.50
2   -2.00
3   -3.00
4   -4.25
5    0.50
6    1.00
现在,使用g作为带有cumsum的groupby

df.groupby(g).cumsum()
输出:

0    1
1    1
2    2
3    2
4    2
5    3
6    3
Name: values, dtype: int64
   values
0    1.00
1    1.50
2   -2.00
3   -3.00
4   -4.25
5    0.50
6    1.00

我投票结束这个问题,因为SO不是一个代码编写服务。您必须显示您尝试过的代码,并且您的问题需要具体说明您遇到问题的具体位置。我尝试使用shift,添加了一个带正负的条件字段。我就是想不出按连续值分组的部分,而不删除我的日常细节。用代码编辑你的问题,然后重新表述。非常聪明。我从来没有想过要这样做。谢谢@谢谢你。