首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从累计增长中计算月增长率

从累计增长中计算月增长率
EN

Stack Overflow用户
提问于 2018-12-04 23:45:53
回答 2查看 1.4K关注 0票数 3

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

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

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

代码语言:javascript
复制
BV_2018 = 5600000.00
Annual_GR = 0.3
EV_2019 = (BV * 0.3) + BV

我正在使用2018年的最后一个月来预测2019年的第一个月。

代码语言:javascript
复制
Last_Month_2018 = 522000.00  
Month_01_2019 = (Last_Month_2018 * CONSTANT) + Last_Month_2018

在2019年的第二个月我会用

代码语言:javascript
复制
Month_02_2019 = (Month_01_2019 * CONSTANT) + Month_01_2019

...and等等

通过Month_12_2019的Month_01_2019的累积和值需要等于EV_2019。

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

事先谢谢,请不要犹豫,要求进一步澄清。

更多澄清:

代码语言:javascript
复制
# get beginning value (BV)
BV = 522000.00

# get desired end value (EV)
EV = 7280000.00

我们正试图通过计算12个月总数的累积和,从BV到EV (这是一个累积和)。每个月的总数将比前一个月增加百分之一,这个月在几个月之间是稳定的。我想解决的就是这个百分点的增长。

记住,BV是前一年的最后一个月。我们的预测(即第一个月至第12个月)将由BV计算。所以,我认为从BV到EV再加上BV是有意义的。然后,将BV及其值从列表中删除,将EV作为月1到12个月的累计总和。

我设想在这样的函数中使用这个常量:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-05 02:59:36

r = 1 + monthly_rate。那么,我们要解决的问题是

r + ... + r**12 = EV/BV。我们可以使用numpy来获得数值解。这在实践中应该是比较快的。我们正在求解一个多项式r + ... + r**12 - EV/BV = 0,并从r中恢复月利率。会有十二个复杂的根源,但只有一个真正积极的根源--这就是我们想要的。

代码语言:javascript
复制
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

一些评论:

  1. roots.imag == 0在某些情况下可能有问题,因为根使用数字算法。作为另一种选择,我们可以在所有具有正实部分的根中选择一个虚部最少的根(绝对值)。
  2. 我们可以用同样的方法来获得其他时间间隔的费率。例如,对于每周利率,我们可以用13 == 12 + 1代替52 + 1
  3. here所述,上述多项式有根的解。

性能的最新情况。我们也可以将其描述为一个不动点问题,即寻找函数的不动点。

代码语言:javascript
复制
x = EV/BV * x ** 13 - EV/BV + 1

不动点x将等于(1 + rate)**13

下面的纯Python实现大约比我的机器上的上面的numpy版本快四倍。

代码语言:javascript
复制
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的帮助下,我们可以使它运行得更快。

票数 2
EN

Stack Overflow用户

发布于 2018-12-05 02:14:48

我不确定这是否有效(告诉我,如果没有),但试试这个。

代码语言:javascript
复制
def get_value(start, end, times, trials=100, _amount=None, _last=-1, _increase=None):
    #don't call with _amount, _last, or _increase! Only start, end and times
    if _amount is None:
        _amount = start / times
    if _increase is None:
        _increase = start / times

    attempt = 1
    for n in range(times):
        attempt = (attempt * _amount) + attempt
    if attempt > end:
        if _last != 0:
            _increase /= 2
            _last = 0
        _amount -= _increase
    elif attempt < end:
        if _last != 1:
            _increase /= 2
            _last = 1
        _amount += _increase
    else:
        return _amount

    if trials <= 0:
        return _amount

    return get_value(start, end, times, trials=trials-1,
             _amount=_amount, _last=_last, _increase=_increase)

告诉我它是否有效。

像这样使用:

代码语言:javascript
复制
get_value(522000.00, 7280000.00, 12)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53623077

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档