Python 3.x 如何使用Python创建摊销表,包括图表?

Python 3.x 如何使用Python创建摊销表,包括图表?,python-3.x,Python 3.x,我正在测试这个代码 import pandas as pd from datetime import date import numpy as np from collections import OrderedDict from dateutil.relativedelta import * def amortize(principal, interest_rate, years, addl_principal=0, annual_payments=12, start_date=date.

我正在测试这个代码

import pandas as pd
from datetime import date
import numpy as np
from collections import OrderedDict
from dateutil.relativedelta import *


def amortize(principal, interest_rate, years, addl_principal=0, annual_payments=12, start_date=date.today()):

    pmt = -round(np.pmt(interest_rate/annual_payments, years*annual_payments, principal), 2)
    # initialize the variables to keep track of the periods and running balances
    p = 1
    beg_balance = principal
    end_balance = principal

    while end_balance > 0:

        # Recalculate the interest based on the current balance
        interest = round(((interest_rate/annual_payments) * beg_balance), 2)

        # Determine payment based on whether or not this period will pay off the loan
        pmt = min(pmt, beg_balance + interest)
        principal = pmt - interest

        # Ensure additional payment gets adjusted if the loan is being paid off
        addl_principal = min(addl_principal, beg_balance - principal)
        end_balance = beg_balance - (principal + addl_principal)

        yield OrderedDict([('Month',start_date),
                           ('Period', p),
                           ('Begin Balance', beg_balance),
                           ('Payment', pmt),
                           ('Principal', principal),
                           ('Interest', interest),
                           ('Additional_Payment', addl_principal),
                           ('End Balance', end_balance)])

        # Increment the counter, balance and date
        p += 1
        start_date += relativedelta(months=1)
        beg_balance = end_balance


schedule = pd.DataFrame(amortize(700000, .04, 30, addl_principal=200, start_date=date(2016, 1,1)))
schedule.head()


schedule.tail()


schedule1, stats1 = amortization_table(100000, .04, 30, addl_principal=50, start_date=date(2016,1,1))
schedule2, stats2 = amortization_table(100000, .05, 30, addl_principal=200, start_date=date(2016,1,1))
schedule3, stats3 = amortization_table(100000, .04, 15, addl_principal=0, start_date=date(2016,1,1))

pd.DataFrame([stats1, stats2, stats3])


additional_payments = [0, 50, 200, 500]
fig, ax = plt.subplots(1, 1)

for pmt in additional_payments:
    result, _ = amortization_table(100000, .04, 30, addl_principal=pmt, start_date=date(2016,1,1))
    ax.plot(result['Month'], result['End Balance'], label='Addl Payment = ${}'.format(str(pmt)))
plt.title("Pay Off Timelines")
plt.ylabel("Balance")
ax.legend();
我从下面的链接中找到了代码:

示例代码似乎适用于发布它的人,但对我来说,我看到的只是以下错误

NameError: name 'amortization_table' is not defined

如果在中的摊销表上按ctrl+F组合键,则可以解决此问题。在“分析时间”部分下。。。下面的代码块定义了一个表。另请参阅笔记本-

def摊销表(利率、年数、付款年数、本金、添加本金=0、开始日期=date.today()):
“”“根据贷款详细信息计算摊销计划
Args:
利率:该贷款的年利率
年份:贷款的年数
付款年度:一年中的付款数量
本金:借款金额
addl_本金(可选):每个期间需要支付的额外款项。如果未提供任何款项,则假设为0。
必须是小于0的值,函数将把正值转换为
消极的
开始日期(可选):开始日期。如果没有提供,将从下个月的第一个月开始
返回:
计划:作为数据帧的摊销计划
摘要:汇总支付信息的数据框
"""
#确保额外付款为负数
如果addl_principal>0:
addl_principal=-addl_principal
#创建付款日期的索引
rng=pd.date\u range(开始日期,期间=年*付款年,频率='MS')
rng.name=“付款日期”
#将摊销计划建立为一个数据框架
df=pd.DataFrame(索引=rng,列=[‘付款’、‘本金’、‘利息’,
'Addl_Principal','Curr_Balance'],dtype='float')
#按时段添加索引(从1开始,而不是从0开始)
df.reset_索引(原地=真)
df.index+=1
df.index.name=“期间”
#使用内置Numpy函数计算付款、本金和利息金额
每笔付款=np.pmt(利率/付款年份、年份*付款年份、本金)
df[“付款”]=每笔付款
df[“本金”]=np.ppmt(利率/付款年度,df.index,年度*付款年度,本金)
df[“利息”]=np.ipmt(利率/付款年、df.index、年*付款年、本金)
#四舍五入
df=df.圆形(2)
#加上额外的本金支付
df[“添加主体”]=添加主体
#存储累计本金付款,并确保其永远不会超过原始本金
df[“累计本金”]=(df[“本金”]+df[“累计本金”])。cumsum()
df[“累积原则”]=df[“累积原则”].clip(下限=-原则)
#计算每个期间的当前余额
df[“当前余额”]=本金+df[“累计本金”]
#确定最后的付款日期
尝试:

last_payment=df.query(“Curr_Balance”)此函数已在您提供的链接中更新。实际数字也不同。
def amortization_table(interest_rate, years, payments_year, principal, addl_principal=0, start_date=date.today()):
""" Calculate the amortization schedule given the loan details

 Args:
    interest_rate: The annual interest rate for this loan
    years: Number of years for the loan
    payments_year: Number of payments in a year
    principal: Amount borrowed
    addl_principal (optional): Additional payments to be made each period. Assume 0 if nothing provided.
                               must be a value less then 0, the function will convert a positive value to
                               negative
    start_date (optional): Start date. Will start on first of next month if none provided

Returns:
    schedule: Amortization schedule as a pandas dataframe
    summary: Pandas dataframe that summarizes the payoff information
"""
# Ensure the additional payments are negative
if addl_principal > 0:
    addl_principal = -addl_principal

# Create an index of the payment dates
rng = pd.date_range(start_date, periods=years * payments_year, freq='MS')
rng.name = "Payment_Date"

# Build up the Amortization schedule as a DataFrame
df = pd.DataFrame(index=rng,columns=['Payment', 'Principal', 'Interest', 
                                     'Addl_Principal', 'Curr_Balance'], dtype='float')

# Add index by period (start at 1 not 0)
df.reset_index(inplace=True)
df.index += 1
df.index.name = "Period"

# Calculate the payment, principal and interests amounts using built in Numpy functions
per_payment = np.pmt(interest_rate/payments_year, years*payments_year, principal)
df["Payment"] = per_payment
df["Principal"] = np.ppmt(interest_rate/payments_year, df.index, years*payments_year, principal)
df["Interest"] = np.ipmt(interest_rate/payments_year, df.index, years*payments_year, principal)

# Round the values
df = df.round(2) 

# Add in the additional principal payments
df["Addl_Principal"] = addl_principal

# Store the Cumulative Principal Payments and ensure it never gets larger than the original principal
df["Cumulative_Principal"] = (df["Principal"] + df["Addl_Principal"]).cumsum()
df["Cumulative_Principal"] = df["Cumulative_Principal"].clip(lower=-principal)

# Calculate the current balance for each period
df["Curr_Balance"] = principal + df["Cumulative_Principal"]

# Determine the last payment date
try:
    last_payment = df.query("Curr_Balance <= 0")["Curr_Balance"].idxmax(axis=1, skipna=True)
except ValueError:
    last_payment = df.last_valid_index()

last_payment_date = "{:%m-%d-%Y}".format(df.loc[last_payment, "Payment_Date"])

# Truncate the data frame if we have additional principal payments:
if addl_principal != 0:

    # Remove the extra payment periods
    df = df.ix[0:last_payment].copy()

    # Calculate the principal for the last row
    df.ix[last_payment, "Principal"] = -(df.ix[last_payment-1, "Curr_Balance"])

    # Calculate the total payment for the last row
    df.ix[last_payment, "Payment"] = df.ix[last_payment, ["Principal", "Interest"]].sum()

    # Zero out the additional principal
    df.ix[last_payment, "Addl_Principal"] = 0

# Get the payment info into a DataFrame in column order
payment_info = (df[["Payment", "Principal", "Addl_Principal", "Interest"]]
                .sum().to_frame().T)

# Format the Date DataFrame
payment_details = pd.DataFrame.from_items([('payoff_date', [last_payment_date]),
                                           ('Interest Rate', [interest_rate]),
                                           ('Number of years', [years])
                                          ])
# Add a column showing how much we pay each period.
# Combine addl principal with principal for total payment
payment_details["Period_Payment"] = round(per_payment, 2) + addl_principal

payment_summary = pd.concat([payment_details, payment_info], axis=1)
return df, payment_summary