簡體   English   中英

如何編寫一個有效的函數來計算給定時間段內不同賬戶的平均期末余額

[英]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

我需要該解決方案具有計算效率,因為您可以猜測我們的數據庫中有多少事務。 如果您對此處陳述或暗示的任何內容不清楚,請隨時提出進一步的問題。 謝謝!

您可以將這個問題分解為幾個步驟。 首先,我們需要在數據框中創建一些新列:

  1. 查找從每個日期到結束日期(在您的示例中為今天)的天數。
  2. 在每組"ID" ,獲取之前計算的列之間的差異,以獲得交易之間的天數。 然后,我們使用fillna方法來填充剩余的日期差異(例如,通過使用diff我們得到行之間的差異,但我們錯過了"ID"最近日期和今天日期之間的差異)。 這為我們建立了一個適當的"days between transaction"
  3. 計算加權余額列:只需將"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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM