我有一只像这样的大熊猫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
你在概念上如何做到这一点?
答案 0 :(得分:2)
使用np.where
和notnull
创建一系列[-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)
注意在新的一天开始时重置值。