根据值在日期之间迭代,并从最后日期向前拉数量



我有一个数据框架如下:

import pandas as pd
#Data
data = {'Symbol':['MU', 'F', 'F', 'BX', 'BX', 'GE', 'BX', 'MU'], 
'Date':['2018-08-20', '2018-08-21', '2018-08-22', '2018-08-24', '2018-08-25', '2018-08-27', '2018-08-27', '2018-08-27'],
'Quantity':[28, 30, 30, 3, 3, 5, 4, -28]} 

# Create DataFrame 
df = pd.DataFrame(data) 

# Print the output. 
df 
Symbol  Date    Quantity
0   MU  2018-08-20  28
1   F   2018-08-21  30
2   F   2018-08-22  30
3   BX  2018-08-24  3
4   BX  2018-08-25  3
5   GE  2018-08-27  5
6   BX  2018-08-27  4
7   MU  2018-08-27  -28

我使用以下代码创建每个日期按符号的数量列的累计总和:

df1 = df.groupby(by=['Symbol','Date'])['Quantity'].sum().groupby(level='Symbol').cumsum().reset_index(name='Cumsum')
print (df1)
Symbol        Date  Cumsum
0     BX  2018-08-24       3
1     BX  2018-08-25       6
2     BX  2018-08-27      10
3      F  2018-08-21      30
4      F  2018-08-22      60
5     GE  2018-08-27       5
6     MU  2018-08-20      28
7     MU  2018-08-27       0

现在,对于每个符号,我想列出开始日期和结束日期之间的所有日期(或者今天,如果仍然保留),并将每个日期的最后一个数量向前拉。然后数据看起来像这样:

Symbol  Date    Quantity
BX  2018-08-24  3
BX  2018-08-25  6
BX  2018-08-26  6
BX  2018-08-27  10
F   2018-08-21  30
F   2018-08-22  60
F   2018-08-23  60
F   2018-08-24  60
F   2018-08-25  60
F   2018-08-26  60
F   2018-08-27  60
GE  2018-08-27  5
MU  2018-08-20  28
MU  2018-08-21  28
MU  2018-08-22  28
MU  2018-08-23  28
MU  2018-08-24  28
MU  2018-08-25  28
MU  2018-08-26  28
MU  2018-08-27  0

我该怎么做呢?

尝试先创建merge,再创建merge

df.Date=pd.to_datetime(df.Date)
s = df.groupby('Symbol')['Date'].agg(['first','last'])
s['Date'] = [pd.date_range(x, y)for x, y in zip(s['first'],s['last'])]
out = s['Date'].explode().reset_index().merge(df,how='left').ffill()
out
Out[100]: 
Symbol       Date  Cumsum
0      BX 2018-08-24     3.0
1      BX 2018-08-25     6.0
2      BX 2018-08-26     6.0
3      BX 2018-08-27    10.0
4       F 2018-08-21    30.0
5       F 2018-08-22    60.0
6      GE 2018-08-27     5.0
7      MU 2018-08-20    28.0
8      MU 2018-08-21    28.0
9      MU 2018-08-22    28.0
10     MU 2018-08-23    28.0
11     MU 2018-08-24    28.0
12     MU 2018-08-25    28.0
13     MU 2018-08-26    28.0
14     MU 2018-08-27     0.0

如果我们需要到最后日期8月27日

s = df.groupby('Symbol')['Date'].agg(['first'])
s['Date'] = [pd.date_range(x, max(df['Date']))for x in s['first']]
out = s['Date'].explode().reset_index().merge(df,how='left').ffill()
out
Out[102]: 
Symbol       Date  Cumsum
0      BX 2018-08-24     3.0
1      BX 2018-08-25     6.0
2      BX 2018-08-26     6.0
3      BX 2018-08-27    10.0
4       F 2018-08-21    30.0
5       F 2018-08-22    60.0
6       F 2018-08-23    60.0
7       F 2018-08-24    60.0
8       F 2018-08-25    60.0
9       F 2018-08-26    60.0
10      F 2018-08-27    60.0
11     GE 2018-08-27     5.0
12     MU 2018-08-20    28.0
13     MU 2018-08-21    28.0
14     MU 2018-08-22    28.0
15     MU 2018-08-23    28.0
16     MU 2018-08-24    28.0
17     MU 2018-08-25    28.0
18     MU 2018-08-26    28.0
19     MU 2018-08-27     0.0

当你上次决定删除你的问题时,我已经起草了一个解决方案:)。

我认为你首先需要创建组合,然后合并/映射到原始数据框,并填充值,然后向前填充总和值。

首先从字符串

转换为日期
df['Date'] = pd.to_datetime(df['Date']) #ignore if dtype is already datetime

:

dates = pd.date_range(df['Date'].min(),df['Date'].max(),freq='D')
comb = pd.MultiIndex.from_product((df['Symbol'].unique(),dates))
out = df.assign(cum_quant=df.groupby("Symbol")['Quantity'].cumsum()).merge(
pd.DataFrame(comb.tolist(),columns=['Symbol','Date']),on=['Symbol','Date'],how='right')
out = out.assign(Quantity=out.sort_values("Date").groupby("Symbol")['cum_quant'].ffill()
).dropna(subset=['Quantity']).drop("cum_quant",1)

这将为您提供结果,但是由于在最后一个问题中您的预期输出保留了符号的顺序,因此您可以使用pd.Categorical来确保顺序。如果不需要,可以忽略此块。

cat_sym = pd.Categorical(out['Symbol'],categories=df['Symbol'].unique(),ordered=True)
out = out.assign(Symbol=cat_sym).sort_values(['Date','Symbol']).reset_index(drop=True)

print(out)
Symbol       Date  Quantity
0      MU 2018-08-20      28.0
1      MU 2018-08-21      28.0
2       F 2018-08-21      30.0
3      MU 2018-08-22      28.0
4       F 2018-08-22      60.0
5      MU 2018-08-23      28.0
6       F 2018-08-23      60.0
7      MU 2018-08-24      28.0
8       F 2018-08-24      60.0
9      BX 2018-08-24       3.0
10     MU 2018-08-25      28.0
11      F 2018-08-25      60.0
12     BX 2018-08-25       6.0
13     MU 2018-08-26      28.0
14      F 2018-08-26      60.0
15     BX 2018-08-26       6.0
16     MU 2018-08-27       0.0
17      F 2018-08-27      60.0
18     BX 2018-08-27      10.0
19     GE 2018-08-27       5.0

最新更新