我试图从 Python 中的年增长率(目标)计算月度增长率的常数。

我的问题与 this question 有算术相似之处,但没有完全回答。

例如,如果 2018 年的年总销售额为 5,600,000.00 美元,而我预计明年将增长 30%,那么我预计 2019 年的年总销售额为 7,280,000.00 美元。

BV_2018 = 5600000.00
Annual_GR = 0.3
EV_2019 = (BV * 0.3) + BV

我正在使用 2018 年的最后一个月来预测 2019 年的第一个月
Last_Month_2018 = 522000.00
Month_01_2019 = (Last_Month_2018 * CONSTANT) + Last_Month_2018

对于 2019 年的第二个月,我将使用
Month_02_2019 = (Month_01_2019 * CONSTANT) + Month_01_2019

...等等等等

Month_01_2019 到 Month_12_2019 的 累计和 需要等于 EV_2019。

有谁知道如何在 Python 中计算常量?我熟悉 np.cumsum 函数,所以这部分不是问题。我的问题是我无法解决我需要的常量。

预先感谢您,请不要犹豫,要求进一步澄清。

更多说明:
# get beginning value (BV)
BV = 522000.00

# get desired end value (EV)
EV = 7280000.00

我们试图通过计算 [12] 每月总计的累计总和来从 BV 获得 EV(这是一个累计总和)。每个月的总数将比上个月增加 %,并且在几个月内保持不变。我想解决的正是这种增加的百分比。

请记住,BV 是上一年的最后一个月。我们的预测(即第 1 个月到第 12 个月)将根据 BV 进行计算。所以,我认为从 BV 到 EV 加上 BV 是有道理的。然后,只需从列表中删除 BV 及其值,将 EV 作为第 1 个月到第 12 个月的累计总数。

我想象在这样的函数中使用这个常量:
def supplier_forecast_calculator(sales_at_cost_prior_year, sales_at_cost_prior_month, year_pct_growth_expected):
    """
    Calculates monthly supplier forecast

    Example:

    monthly_forecast = supplier_forecast_calculator(sales_at_cost_prior_year = 5600000,
                                                sales_at_cost_prior_month = 522000,
                                                year_pct_growth_expected = 0.30)

    monthly_forecast.all_metrics
    """

    # get monthly growth rate
    monthly_growth_expected = CONSTANT

    # get first month sales at cost
    month1_sales_at_cost = (sales_at_cost_prior_month*monthly_growth_expected)+sales_at_cost_prior_month

    # instantiate lists
    month_list = ['Month 1'] # for months
    sales_at_cost_list = [month1_sales_at_cost] # for sales at cost

    # start loop
    for i in list(range(2,13)):
        # Append month to list
        month_list.append(str('Month ') + str(i))
        # get sales at cost and append to list
        month1_sales_at_cost = (month1_sales_at_cost*monthly_growth_expected)+month1_sales_at_cost
        # append month1_sales_at_cost to sales at cost list
        sales_at_cost_list.append(month1_sales_at_cost)

    # add total to the end of month_list
    month_list.insert(len(month_list), 'Total')

    # add the total to the end of sales_at_cost_list
    sales_at_cost_list.insert(len(sales_at_cost_list), np.sum(sales_at_cost_list))

    # put the metrics into a df
    all_metrics = pd.DataFrame({'Month': month_list,
                            'Sales at Cost': sales_at_cost_list}).round(2)

    # return the df
    return all_metrics

最佳答案

r = 1 + monthly_rate 。那么,我们要解决的问题是
r + ... + r**12 = EV/BV 。我们可以使用 numpy 来获得数值解。这在实践中应该相对较快。我们正在求解多项式 r + ... + r**12 - EV/BV = 0 并从 r 恢复月费率。将有十二个复根,但只有一个真正的正根——这就是我们想要的。

import numpy as np

# get beginning value (BV)
BV = 522000.00

# get desired end value (EV)
EV = 7280000.00


def get_monthly(BV, EV):
    coefs = np.ones(13)
    coefs[-1] -= EV / BV + 1
    # there will be a unique positive real root
    roots = np.roots(coefs)
    return roots[(roots.imag == 0) & (roots.real > 0)][0].real - 1


rate = get_monthly(BV, EV)
print(rate)
# 0.022913299846925694

一些评论:
  • roots.imag == 0 在某些情况下可能有问题,因为 root 使用数字算法。作为替代方案,我们可以在所有实部为正的根中选择虚部最小(绝对值)的根。
  • 我们可以使用相同的方法获取其他时间间隔的费率。例如,对于每周费率,我们可以将 13 == 12 + 1 替换为 52 + 1
  • 上述多项式有一个根式解,如 here 所示。


  • 性能更新。我们也可以将其定义为不动点问题,即寻找函数的不动点
    x = EV/BV * x ** 13 - EV/BV + 1
    

    固定点 x 将等于 (1 + rate)**13

    以下纯 Python 实现大约比我机器上的上述 numpy 版本快四倍。
    def get_monthly_fix(BV, EV, periods=12):
        ratio = EV / BV
        r = guess = ratio
        while True:
            r = ratio * r ** (1 / periods) - ratio + 1
            if abs(r - guess) < TOLERANCE:
                return r ** (1 / periods) - 1
            guess = r
    

    numba.jit 的帮助下,我们可以使这个运行得更快。

    关于python - 从累计总增长中计算每月增长百分比,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53623077/

    10-12 16:47