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

时间:2017-07-03 17:14:29

标签: 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      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

之后我迷路了。我可以继续改变我的价值观并且有很多if语句,但必须有更好的方法。

2 个答案:

答案 0 :(得分:4)

将0放入肯定中,您可以使用shift-compare-cumsum模式:

{ 
   id: STAR_ID
   fullname: FULLNAME, 
   date_of_birth: DATE_OF_BIRTH
   ...
} 

有效,因为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()

答案 1 :(得分:3)

创建群组:

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

现在,将g用作cumsum的组合

df.groupby(g).cumsum()

输出:

   values
0    1.00
1    1.50
2   -2.00
3   -3.00
4   -4.25
5    0.50
6    1.00