首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过计算计算累计列

通过计算计算累计列
EN

Stack Overflow用户
提问于 2020-08-28 15:59:56
回答 2查看 66关注 0票数 2

我有以下数据帧:

代码语言:javascript
复制
data = {'month': {0: Timestamp('2019-01-01 00:00:00'),
  1: Timestamp('2019-02-01 00:00:00'),
  2: Timestamp('2019-03-01 00:00:00'),
  3: Timestamp('2019-04-01 00:00:00'),
  4: Timestamp('2019-05-01 00:00:00')},
 'base_expenses': {0: 200.0, 1: 200.0, 2: 200.0, 3: 200.0, 4: 200.0},
 'base_contribution': {0: 100.0, 1: 100.0, 2: 100.0, 3: 100.0, 4: 100.0}}

df = pd.DataFrame(data)
df

month   base_expenses   base_contribution
0   2019-01-01  200.0   100.0
1   2019-02-01  200.0   100.0
2   2019-03-01  200.0   100.0
3   2019-04-01  200.0   100.0
4   2019-05-01  200.0   100.0

该数据将代表每月增加额外贡献的投资,并且每月以一定的百分比增长。

例如,投资的起始余额是50000。每个月我们都会将base_contribution添加到余额中。最后,每个月的余额都会以0.6%的速度增长。

我可以使用如下循环计算所有这些:

代码语言:javascript
复制
CURRENT_BALANCE = 50000
MONTHLY_INVESTMENT_RETURN = 0.006

df['base_balance'] = CURRENT_BALANCE
for index, row in df.iterrows():
    if index == 0:
        balance = row['base_contribution'] + row['base_balance']
        balance += balance * MONTHLY_INVESTMENT_RETURN
        df.loc[row.name, 'base_balance'] = balance
    else:
        balance = row['base_contribution'] + df.loc[row.name - 1, 'base_balance']
        balance += balance * MONTHLY_INVESTMENT_RETURN
        df.loc[row.name, 'base_balance'] = balance

结果将是:

代码语言:javascript
复制
    month   base_expenses   base_contribution   base_balance
0   2019-01-01  200.0   100.0   50422.344909
1   2019-02-01  200.0   100.0   50847.407197
2   2019-03-01  200.0   100.0   51275.204349
3   2019-04-01  200.0   100.0   51705.753960
4   2019-05-01  200.0   100.0   52139.073741

我正在处理的真实数据非常大,所以如果可能的话,我更愿意避免这种循环方法。有没有一种方法可以在矢量化的庄园中或在没有循环的情况下做到这一点?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-28 17:32:12

根据这个post,它似乎是不可行的

您可以在每个循环中保存一个ifdf.at也是在数据帧中设置值的一种更快的方法。

代码语言:javascript
复制
balance = df.loc[0, 'base_contribution'] + df.loc[0, 'base_balance']
balance += balance * MONTHLY_INVESTMENT_RETURN
df.at[0, 'base_balance'] = balance

for index, row in df[1:].iterrows():
    balance = row['base_contribution'] + df.loc[row.name - 1, 'base_balance']
    balance += balance * MONTHLY_INVESTMENT_RETURN
    df.at[index, 'base_balance'] = balance

我发现了一些有趣的方法:rollingcumsumexpanding。但是这里什么都不起作用,因为我们不知道base_contribution在start上的值。

票数 0
EN

Stack Overflow用户

发布于 2020-08-28 20:26:13

在base_balance为常数的假设下。

只需一个中间步骤,您就可以做您想做的事情:请记住,您可以将投资分成几个部分,并计算每个部分的回报。

因此,第n个月的起始余额(CURRENT_BALANCE )的结果值可以写为:

代码语言:javascript
复制
df["result_on_start_investment"] =  CURRENT_BALANCE * math.pow(MONTHLY_INVESTMENT_RETURN,  np.arange(len(df)) + 1)

每个月都会增加一笔额外的投资。这笔钱每个月都会得到回报。作为第一步,计算

代码语言:javascript
复制
df["result_on_added_at_month_one"] = base_balance * math.pow(MONTHLY_INVESTMENT_RETURN,  np.arange(len(df)) + 1)

最后,由于在n-1个月的增加货币的收入等于在1个月在2个月增加的货币收入:

代码语言:javascript
复制
df["balance"] = df["result_on_start_investment"] + df["result_on_added_at_month_one"].cumsum()

结果:

代码语言:javascript
复制
month  base_expenses  base_contribution  n  result_on_added_at_month_one  result_on_start_investment       balance
0      0          200.0              100.0  1                    100.643403                50321.701506  50422.344909
1      1          200.0              100.0  2                    101.290946                50645.472848  50847.407197
2      2          200.0              100.0  3                    101.942655                50971.327345  51275.204349
3      3          200.0              100.0  4                    102.598557                51299.278400  51705.753960
4      4          200.0              100.0  5                    103.258679                51629.339502  52139.073741
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63629744

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档