[英]How do I write an efficient function to calculate the average closing balance for different accounts given a time period
我在一家金融机构工作。 在我们的交易表中,我们仅在客户交易时跟踪客户的余额。 例如,如果客户在 10 月 1 日以 200 美元开户,然后在 10 月 8 日提取 50 美元,那么他在交易表中将只有两个条目,一个是 2020/10/01,另一个是2020/10/8。 现在,这个问题的重点是期末余额。 按照这个类比,如果我们使用今天作为截止日期,您会同意客户在 7 天(2020/10/8 - 2020/10/1)的期末余额为 200 美元,在剩余 29 天。
现在,我不确定如何编写此函数。 我一直遇到错误,如果有人能帮助我解决 python 代码和相应的注释,我将不胜感激,这样这对我来说就成为一种有效的学习体验。
这是我拥有的数据集示例:
sample_df = pd.DataFrame({'ID': [15, 16, 15, 15, 16, 17, 17, 16],
'Calendar_Date': ['2020-10-10', '2020-10-12', '2020-10-12', '2020-10-22', '2020-10-28', '2020-10-30', '2020-11-03', '2020-11-04'] ,
'Closing_Balance': [10000, 3000, 6000, 5100, 14500, 25000, 13000, 9000]})
这是我期望的结果:
result_df = pd.DataFrame({'ID':[15, 16, 17],
'Total_Days': [26, 24, 6],
'Average_Account_Balance': [5823.08, 6375.00, 19000]})
为清楚起见:这就是我得出 result_df 的方式:
当 ID = 15 时, Total_Days = (2+10+15) = 27; Average_Account_Balance = ((10000 * 2) + (6000 * 10) + (5100 * 15))/27 = 156500/27 = 5796.3
当 ID = 16 时, Total_Days = (16+7+2) = 25; Average_Account_Balance = ((3000 * 16) + (14500 * 7) + (9000 * 2))/25 = 167500/25 = 6700.00
当 ID = 17 时, Total_Days = (4+3) = 7;
Average_Account_Balance = ((25000 * 4) + (13000 * 3))/7 = 139000/7 = 19857.14
我需要该解决方案具有计算效率,因为您可以猜测我们的数据库中有多少事务。 如果您对此处陈述或暗示的任何内容不清楚,请随时提出进一步的问题。 谢谢!
您可以将这个问题分解为几个步骤。 首先,我们需要在数据框中创建一些新列:
"ID"
,获取之前计算的列之间的差异,以获得交易之间的天数。 然后,我们使用fillna
方法来填充剩余的日期差异(例如,通过使用diff
我们得到行之间的差异,但我们错过了"ID"
最近日期和今天日期之间的差异)。 这为我们建立了一个适当的"days between transaction"
列"Closing_Balance" by the newly created
乘以"Closing_Balance" by the newly created
“交易之间的天数”`列sample_df["days_from_today"] = (pd.to_datetime("11/06/2020").normalize() - sample_df["Calendar_Date"]).dt.days
sample_df["days_between_transactions"] = (sample_df.groupby("ID")["days_from_today"]
.diff(-1)
.fillna(sample_df["days_from_today"])
.astype(int))
sample_df["weighted_balance"] = sample_df["Closing_Balance"] * sample_df["days_between_transactions"]
print(sample_df)
ID Calendar_Date Closing_Balance days_from_today days_between_transactions weighted_balance
0 15 2020-10-10 10000 27 2 20000
1 16 2020-10-12 3000 25 16 48000
2 15 2020-10-12 6000 25 10 60000
3 15 2020-10-22 5100 15 15 76500
4 16 2020-10-28 14500 9 7 101500
5 17 2020-10-30 25000 7 4 100000
6 17 2020-11-03 13000 3 3 39000
7 16 2020-11-04 9000 2 2 18000
现在我们已经创建了额外的列,我们可以执行groupby -> aggregation
操作来获取"weighted_balance"
列的sum
,并将其除以每个唯一"ID"
的"days_from_today"
的max
aggregated_df = sample_df.groupby("ID").agg(
weighted_total_account_balance=("weighted_balance", "sum"),
total_days=("days_from_today", "max")
)
aggregated_df["average_account_balance"] = aggregated_df["weighted_total_account_balance"] / aggregated_df["total_days"]
print(aggregated_df)
weighted_total_account_balance total_days average_account_balance
ID
15 156500 27 5796.296296
16 167500 25 6700.000000
17 139000 7 19857.142857
我注意到我们的结果有轻微的差异,我相信这可能是由于我们的时区不同(今天对我来说是 11/6/2020,不确定你是什么时间/天)所以我们的“total_days”可能不同。
此外,如果您的数据非常大,我建议使用DataFrame.eval
来执行算术运算。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.