pandas 创建累积产品,并在每个月末重置为1

n3h0vuf2  于 2023-01-24  发布在  其他
关注(0)|答案(2)|浏览(78)

我尝试在Dataframe df中创建一个新列CumReturn,其中包含当月的累计产品,并尝试在每个月末将cum_prod()重置为1(如果EndMonth == 1),然后使用累计产品重新开始。

df:
Date        EndMonth  ID1  Return
2023-01-30     0       A     0.95
2023-01-30     0       B     0.98
2023-01-31     1       A     1.01
2023-01-31     1       B     1.02
2023-02-01     0       A     1.05
2023-02-01     0       B     0.92
2023-02-02     0       A     0.97
2023-02-02     0       B     0.99

我试着用它来做:df [“累计退货”] = np.其中(df [“月末”] == 1,1,df [“退货”].groupby(“ID 1”).cumprod())
当我这样做的时候,我得到的2023-02-02是整个时期的累积乘积,而不仅仅是从2月初开始的。
再现性:

import pandas as pd
df1 = pd.DataFrame({
    'Date':['2023-01-30', '2023-01-30', '2023-01-31', '2023-01-31', '2023-02-01', '2023-02-01', '2023-02-02', '2023-02-02'],
    'EndMonth':[0, 0, 1, 1, 0, 0, 0, 0],
    'ID1':['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'],
    'Return':[0.95, 0.98, 1.01, 1.02, 1.05, 0.92, 0.97, 0.99]})
df1 = df1.set_index('Date')

非常感谢!

nlejzf6q

nlejzf6q1#

IIUC用途:

df1.index = pd.to_datetime(df1.index)

df1['CumReturn'] = (df1['Return'].add(1)
                                 .groupby([df1['ID1'], pd.Grouper(freq='m')])
                                 .cumprod()
                                 .sub(1))
print (df1)
            EndMonth ID1  Return  CumReturn
Date                                       
2023-01-30         0   A    0.95     0.9500
2023-01-30         0   B    0.98     0.9800
2023-01-31         1   A    1.01     2.9195
2023-01-31         1   B    1.02     2.9996
2023-02-01         0   A    1.05     1.0500
2023-02-01         0   B    0.92     0.9200
2023-02-02         0   A    0.97     3.0385
2023-02-02         0   B    0.99     2.8208
hyrbngr7

hyrbngr72#

看起来您想要:

# set up grouper per ID and month
g = df1.groupby(['ID1', pd.to_datetime(df1.index).month])['Return']

# get cumprod per month with starting value being 1
# (we divide by the first value)
df1['CumProd'] = g.cumprod().div(g.transform('first'))

输出:

EndMonth ID1  Return  CumProd
Date                                     
2023-01-30         0   A    0.95     1.00
2023-01-30         0   B    0.98     1.00
2023-01-31         1   A    1.01     1.01
2023-01-31         1   B    1.02     1.02
2023-02-01         0   A    1.05     1.00
2023-02-01         0   B    0.92     1.00
2023-02-02         0   A    0.97     0.97
2023-02-02         0   B    0.99     0.99

相关问题