def LMDI(*,data_t:object, data_0:object, yt:float, y0:float) -> object: """ Args: data_t:t期结果值,example data_0:基期结果值 yt: t期结果值 y0: 基期结果值 Returns: object['x']['key'] 代表x的key,x为自变量 object['x']['key']['x0']: 基期值 object['x']['key']['xt']: t期值 object['x']['key']['change']: 变动值 object['x']['key']['changeRate']: 变动率,即同比值 object['x']['key']['contribute']: LMDI计算得贡献度 object['x']['key']['contributeRate']: 基期贡献率, LMDI计算得贡献度 / y0 object['x']['key']['changeContributeRate']: 变动值贡献率, LMDI计算得贡献度 / object['y']['change'] object['y'] y代表因变量 object['y']['y0']: 基期值 object['y']['yt']: 本期值 object['y']['change']: 变动值 object['y']['changeRate']: 变动率,即同比值 Raises: ValueError: data_t/data_0的内容相乘不等于yt/y0, data_t和data_0的key名称及数量不相等 """ from functools import reduce import numpy as np # 对参数进行校验 data_0_comp = reduce(lambda x,y:x*y,data_0.values()) data_t_comp = reduce(lambda x,y:x*y,data_t.values()) if ( data_t_comp - yt > 1 or data_t_comp - yt <-1) : # 考虑到float的计算精度,这里放了gap值不能大于1 raise ValueError('data_t的内容相乘不等于tt') elif (data_0_comp - y0 > 1 or data_0_comp - y0 <-1): raise ValueError('data_0的内容相乘不等于tt') elif data_t.keys() != data_0.keys(): raise ValueError('data_t和data_0的key名称及数量不相等') def Delta_XX(*,yt,y0,xt,x0): # 计算LMDI中每个参数的Δ值 def L(yt,y0): if yt == y0: return 0 else: return (yt-y0)/(np.log(yt) - np.log(y0)) return L(yt,y0)*np.log(xt/x0) x = {} for key in data_t.keys(): x[key] = {} x[key]['x0'] = data_0[key] x[key]['xt'] = data_t[key] x[key]['change'] = data_t[key]- data_0[key] x[key]['changeRate'] = 0 if data_0[key]==0 or data_0[key]==0 or data_0[key]=="" else (data_t[key]- data_0[key]) / data_0[key] x[key]['contribute'] = Delta_XX(yt=yt,y0=y0,xt=data_t[key], x0=data_0[key]) x[key]['contributeRate'] = 0 if y0==0 else x[key]['contribute'] / y0 x[key]['changeContributeRate'] = 0 if yt-y0 == 0 else x[key]['contribute'] / (yt-y0) y = {} y['y0'] = y0 y['yt'] = yt y['change'] = yt - y0 y['changeRate'] = 0 if yt ==0 or y0==0 else (yt-y0)/yt result = { "x":x, "y":y } return result# 计算结果y0 = 1078122 # 基期结果值yt = 1469699 # t期结果值data_t = { "uv":19087, "m": 0.25, "d": 308} # t期分解值集合data_0 = { "uv":20032, "m": 0.23, "d": 234} # 基期分解值集合LMDI(data_t=data_t,data_0=data_0,yt=yt,y0=y0)
参考:LMDI 理论推导详解【从理论到Python-MATLAB实现(编程实现)】_春风惹人醉的博客-CSDN博客_lmdi模型python实现
来源地址:https://blog.csdn.net/fzcg1994/article/details/128922961