Панды капитализации сложных интересов - PullRequest
0 голосов
/ 22 февраля 2019

Я пишу эмуляцию банковского депозитного счета в пандах.Я застрял с Сложные проценты (Это результат реинвестирования процентов, так что проценты в следующем периоде начисляются на основную сумму плюс ранее накопленные проценты.)

Пока что яиметь следующий код:

import pandas as pd
from pandas.tseries.offsets import MonthEnd
from datetime import datetime

# Create a date range
start = '21/11/2017'
now = datetime.now()
date_rng = pd.date_range(start=start, end=now, freq='d')

# Create an example data frame with the timestamp data
df = pd.DataFrame(date_rng, columns=['Date'])

# Add column (EndOfMonth) - shows the last day of the current month
df['LastDayOfMonth'] = pd.to_datetime(df['Date']) + MonthEnd(0)

# Add columns for interest, Sasha, Artem, Total, Description
df['Debit'] = 0
df['Credit'] = 0
df['Total'] = 0
df['Description'] = ''

# Iterate through the DataFrame to set "IsItLastDay" value
for i in df:
    df['IsItLastDay'] = (df['LastDayOfMonth'] == df['Date'])

# Add the transaction of the first deposit
df.loc[df.Date == '2017-11-21', ['Debit', 'Description']] = 10000, "First deposit"

# Calculate the principal sum (It the summ of all deposits minus all withdrows plus all compaund interests)
df['Total'] = (df.Debit - df.Credit).cumsum()

# Calculate interest per day and Cumulative interest
# 11% is the interest rate per year
df['InterestPerDay'] = (df['Total'] * 0.11) / 365
df['InterestCumulative'] = ((df['Total'] * 0.11) / 365).cumsum()

# Change the order of columns
df = df[['Date', 'LastDayOfMonth', 'IsItLastDay', 'InterestPerDay', 'InterestCumulative', 'Debit', 'Credit', 'Total', 'Description']]

df.to_excel("results.xlsx")

Выходной файл выглядит нормально, но мне нужно следующее:

  1. Столбец "InterestCumulative" добавляет в столбец "Всего" в последнийдень каждого месяца (сложение процентов)
  2. В начале каждого месяца столбец «Начисление процентов» должен быть очищен (поскольку проценты были добавлены к основной сумме).

enter image description here

И я понятия не имею, как это сделать.

Есть ли у вас какие-либо мысли по этому поводу?Спасибо заранее!

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Менее элегантное решение.

# Get the values for the first and last days of months respectively
first_days = df.groupby(by=df['Date'].dt.month, as_index=False).first()
last_days = df.groupby(by=df['Date'].dt.month, as_index=False).last()

print(df.loc[df['Date'].isin(first_days['Date']), 'InterestCumulative'])
print(df.loc[df['Date'].isin(last_days['Date']), 'Total'])

# Replace first day interest with 0s
df.loc[df['Date'].isin(first_days['Date']), 'InterestCumulative'] = 0

# Adds last day 'Interestcumulative' to 'Total'
df.loc[df['Date'].isin(last_days['Date']), 'Total'] = (
            last_days['Total']
            + last_days['InterestCumulative']
        ).values

print(df.loc[df['Date'].isin(first_days['Date']), 'InterestCumulative'])
print(df.loc[df['Date'].isin(last_days['Date']), 'Total'])
0 голосов
/ 22 февраля 2019

Вам нужно будет выполнить цикл, так как общее количество меняется в зависимости от предыдущих строк, что затем влияет на более поздние строки.В результате ваши текущие расчеты процентов неверны.

total = 0
cumulative_interest = 0

total_per_day = []
interest_per_day = []
cumulative_per_day = []
for day in df.itertuples():
    total += day.Debit - day.Credit
    interest = total * 0.11 / 365
    cumulative_interest += interest

    if day.IsItLastDay:
        total += cumulative_interest

    total_per_day.append(total)
    interest_per_day.append(interest)
    cumulative_per_day.append(cumulative_interest)

    if day.IsItLastDay:
        cumulative_interest = 0

df.Total = total_per_day
df.InterestPerDay = interest_per_day
df.InterestCumulative = cumulative_per_day

К сожалению, это выглядит намного более запутанно, но это то, что происходит, когда значения зависят от предыдущих значений.В зависимости от ваших точных требований, могут быть хорошие способы упростить это с помощью математики, но в остальном это то, что у вас есть.

Я записал это непосредственно в stackoverflow, поэтому он может быть не идеальным.

...