如何通过每日重置有条件地累积熊猫行

时间:2016-07-14 12:17:16

标签: python-3.x pandas

我有一只像这样的大熊猫df

                    price  quantity initiator
time                                          
2016-07-13 16:19:31   6.20      8000         B
2016-07-13 16:19:45   6.19      5176         S
2016-07-13 16:25:08   6.24     15000         NaN
2016-07-13 16:25:08   6.24      2847         S
2016-07-13 16:25:08   6.24     39829         B
2016-07-13 16:25:08   6.24      2398         B
2016-07-13 16:25:08   6.24      1844         NaN
2016-07-13 16:25:08   6.24      9538         S
2016-07-13 16:25:08   6.24       459         B
2016-07-13 16:25:08   6.24      1082         B

我想添加一个累积数量的列,每天从零开始。条件是如果发起者是B则数量是正数,如果S是负数并且如果NaN不计数。

因此,使用上述数据,我的新列将如下所示:

acc_quantity
8000
2824
2824
337
40166
42564
42564
33026
33485
34567

你在概念上如何做到这一点?

1 个答案:

答案 0 :(得分:2)

使用np.wherenotnull创建一系列[-1, 0, 1] s。将此系列乘以df.quantity并使用cumsum

我们将构建一个功能来执行上述操作,并将其应用于我们按天分组的groupby

import pandas as pd
import numpy as np
from StringIO import StringIO

text = """time       price  quantity  initiator
2016-07-13 16:19:31   6.20      8000         B
2016-07-13 16:19:45   6.19      5176         S
2016-07-13 16:25:08   6.24     15000         NaN
2016-07-13 16:25:08   6.24      2847         S
2016-07-13 16:25:08   6.24     39829         B
2016-07-13 16:25:08   6.24      2398         B
2016-07-13 16:25:08   6.24      1844         NaN
2016-07-13 16:25:08   6.24      9538         S
2016-07-13 16:25:08   6.24       459         B
2016-07-13 16:25:08   6.24      1082         B
2016-07-14 16:19:31   6.20      8000         B
2016-07-14 16:19:45   6.19      5176         S
2016-07-14 16:25:08   6.24     15000         NaN
2016-07-14 16:25:08   6.24      2847         S
2016-07-14 16:25:08   6.24     39829         B
2016-07-14 16:25:08   6.24      2398         B
2016-07-14 16:25:08   6.24      1844         NaN
2016-07-14 16:25:08   6.24      9538         S
2016-07-14 16:25:08   6.24       459         B
2016-07-14 16:25:08   6.24      1082         B"""

df = pd.read_csv(StringIO(text), sep='\s{2,}', engine='python', index_col=0, parse_dates=[0])

def accumulator(df):
    initiator = np.where(df.initiator == 'B', 1, -1) * df.initiator.notnull()
    return pd.DataFrame((df.quantity * initiator).cumsum(), df.index, ['acc_quantity'])

pd.concat([df, df.groupby(df.index.strftime('%Y-%m-%d')).apply(accumulator)], axis=1)

注意在新的一天开始时重置值。

enter image description here