我有以下数据帧:
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%的速度增长。
我可以使用如下循环计算所有这些:
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结果将是:
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我正在处理的真实数据非常大,所以如果可能的话,我更愿意避免这种循环方法。有没有一种方法可以在矢量化的庄园中或在没有循环的情况下做到这一点?
发布于 2020-08-28 17:32:12
根据这个post,它似乎是不可行的
您可以在每个循环中保存一个if。df.at也是在数据帧中设置值的一种更快的方法。
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我发现了一些有趣的方法:rolling、cumsum和expanding。但是这里什么都不起作用,因为我们不知道base_contribution在start上的值。
发布于 2020-08-28 20:26:13
在base_balance为常数的假设下。
只需一个中间步骤,您就可以做您想做的事情:请记住,您可以将投资分成几个部分,并计算每个部分的回报。
因此,第n个月的起始余额(CURRENT_BALANCE )的结果值可以写为:
df["result_on_start_investment"] = CURRENT_BALANCE * math.pow(MONTHLY_INVESTMENT_RETURN, np.arange(len(df)) + 1)每个月都会增加一笔额外的投资。这笔钱每个月都会得到回报。作为第一步,计算
df["result_on_added_at_month_one"] = base_balance * math.pow(MONTHLY_INVESTMENT_RETURN, np.arange(len(df)) + 1)最后,由于在n-1个月的增加货币的收入等于在1个月在2个月增加的货币收入:
df["balance"] = df["result_on_start_investment"] + df["result_on_added_at_month_one"].cumsum()结果:
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.073741https://stackoverflow.com/questions/63629744
复制相似问题