Python | 复合成本指数

发布时间:2026/9/24 14:02:45
Python | 复合成本指数 背景为物流行业箱成本需区分仓储/物流/管理三类成本计算复合成本指数。运行环境jupyter notebook(python 3.12.7)1.复合成本计算公式解读2.设定权重值用示例数据运行python代码3.根据成本波动率自动调整权重4.整合2和3的代码根据成本波动率自动调整权重并运行出复合成本指数的结果步骤1公式理解步骤2示例数据的python运行代码import pandas as pd import numpy as np import matplotlib.pyplot as plt import matplotlib.ticker as mtick # 设置中文显示 plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False # 生成示例数据2023年月度数据 np.random.seed(2023) dates pd.date_range(2023-01, periods12, freqME) data { 仓储成本(元/箱): np.round(np.random.uniform(2.5, 3.5, 12) np.sin(np.arange(12)*0.5)*0.3, 2), 物流成本(元/箱): np.round(np.random.uniform(8.0, 12.0, 12) np.cos(np.arange(12)*0.4)*1.2, 2), 管理成本(元/箱): np.round(np.linspace(1.8, 2.3, 12) np.random.normal(0, 0.1, 12), 2) } df pd.DataFrame(data, indexdates) # 计算复合成本指数权重系数仓储1 : 物流2 : 管理0.5 weights np.array([1, 2, 0.5]) df[复合成本指数] df.apply(lambda x: np.dot(x.values, weights)/weights.sum(), axis1) # 成本构成分析可视化 fig, axes plt.subplots(2, 2, figsize(16, 12)) # 1. 成本趋势分析 ax axes[0,0] df[[仓储成本(元/箱), 物流成本(元/箱), 管理成本(元/箱)]].plot(axax, markero) ax.set_title(单箱成本分项趋势, fontsize14) ax.set_ylabel(成本(元)) ax.yaxis.set_major_formatter(mtick.FormatStrFormatter(%.1f)) ax.grid(True, alpha0.3) # 2. 复合指数趋势 ax axes[0,1] df[复合成本指数].plot(axax, colorpurple, markers) ax.set_title(复合成本指数变化趋势, fontsize14) ax.set_ylabel(指数值) ax.axhline(df[复合成本指数].mean(), colorr, linestyle--, labelf年度均值({df[复合成本指数].mean():.2f})) ax.legend() ax.grid(True, alpha0.3) # 3. 成本构成堆叠图 ax axes[1,0] components df[[仓储成本(元/箱), 物流成本(元/箱), 管理成本(元/箱)]].T ax.stackplot(df.index, components, labels[仓储, 物流, 管理], colors[#4CAF50, #2196F3, #FF9800]) ax.set_title(成本构成堆叠分析, fontsize14) ax.set_ylabel(累计成本(元)) ax.legend(locupper left) ax.xaxis.set_tick_params(rotation45) ax.grid(True, alpha0.3) # 4. 年度成本占比 ax axes[1,1] total df[[仓储成本(元/箱), 物流成本(元/箱), 管理成本(元/箱)]].sum() ax.pie(total, labelstotal.index, autopct%1.1f%%, colors[#4CAF50, #2196F3, #FF9800], startangle90, wedgepropsdict(width0.4)) ax.set_title(年度成本结构占比, fontsize14) plt.tight_layout() plt.show() # 打印详细数据报告 print(月度成本明细报告) print(df) print(\n年度成本汇总) print(df[[仓储成本(元/箱), 物流成本(元/箱), 管理成本(元/箱)]].sum().to_string())运行结果对比表格计算结果做验证Tips参数说明ME每月最后一天Month EndME-S每月第一天Month StartQE季度最后一天YE年度最后一天步骤3根据成本波动率自动调整权重波动率越低 → 权重越高波动率越高 → 权重越低示例数据与代码import numpy as np import pandas as pd import matplotlib.pyplot as plt # 设置中文显示 plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False # # 生成示例数据2023年季度数据 # np.random.seed(2023) dates pd.date_range(2023-Q1, periods8, freqQE) # 生成8个季度末日期 data { # 仓储成本 - 低波动性标准差0.3 仓储成本: np.round(50 np.cumsum(np.random.normal(0, 0.3, 8)), 2), # 物流成本 - 高波动性标准差1.5 物流成本: np.round(80 np.cumsum(np.random.normal(0, 1.5, 8)), 2), # 管理成本 - 中波动性标准差0.8 管理成本: np.round(30 np.cumsum(np.random.normal(0, 0.8, 8)), 2) } df pd.DataFrame(data, indexdates) # # 动态权重计算 # # 计算波动率标准差 volatility df.std() # 计算动态权重波动率越小权重越高 epsilon 1e-6 # 防止除零 weights (1 / (volatility epsilon)).round(2) weights / weights.sum() # 标准化为总和1 # # 可视化分析 # fig, (ax1, ax2) plt.subplots(2, 1, figsize(10, 8)) # 1. 成本趋势图 df.plot(axax1, markero) ax1.set_title(成本项目趋势分析单位万元) ax1.set_ylabel(成本金额) ax1.grid(True, alpha0.3) # 2. 波动率与权重对比 ax2.bar(volatility.index, volatility, alpha0.7, label波动率标准差) ax2_twin ax2.twinx() ax2_twin.plot(weights.index, weights, ro-, markersize8, label动态权重) ax2.set_title(波动率与动态权重关系) ax2.set_ylabel(波动率) ax2_twin.set_ylabel(权重系数, colorr) ax2_twin.tick_params(axisy, labelcolorr) # 合并图例 lines, labels ax2.get_legend_handles_labels() lines2, labels2 ax2_twin.get_legend_handles_labels() ax2.legend(lines lines2, labels labels2, locupper left) plt.tight_layout() plt.show() # 打印计算结果 print(波动率分析报告) print(volatility.to_string()) print(\n动态权重分配) print(weights.to_string())运行结果步骤4整合以上代码根据成本波动率自动调整权重并运行出复合成本指数的结果代码import pandas as pd import numpy as np import matplotlib.pyplot as plt import matplotlib.ticker as mtick from matplotlib.gridspec import GridSpec # 设置中文显示 plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False # # 数据生成带时间序列特征 # np.random.seed(2023) dates pd.date_range(2022-01, periods24, freqME) # 生成24个月数据用于滚动计算 data { 仓储成本: np.round(3 np.sin(np.arange(24)*0.5)*0.3 np.random.normal(0, 0.1, 24), 2), 物流成本: np.round(10 np.cos(np.arange(24)*0.4)*1.2 np.random.normal(0, 0.5, 24), 2), 管理成本: np.round(2 np.linspace(0, 0.5, 24) np.random.normal(0, 0.2, 24), 2) } df pd.DataFrame(data, indexdates) # # 动态权重计算滚动窗口 # def calculate_dynamic_weights(df, window12): 滚动计算动态权重 weights pd.DataFrame(indexdf.index, columnsdf.columns) for i in range(window-1, len(df)): # 提取滚动窗口数据 window_data df.iloc[i-window1:i1] # 计算波动率 volatility window_data.std() # 计算动态权重波动率越小权重越高 epsilon 1e-6 adjusted_weights 1 / (volatility epsilon) normalized_weights adjusted_weights / adjusted_weights.sum() weights.iloc[i] normalized_weights return weights[window-1:] # 去除前window-1个空值 # 计算动态权重12个月滚动 dynamic_weights calculate_dynamic_weights(df, window12) # 计算复合成本指数仅计算有效窗口期 def calculate_composite_index(row, weights): 根据动态权重计算复合指数 try: valid_weights weights.loc[row.name] return np.dot(row.values, valid_weights.values) except KeyError: return np.nan # 对无权重数据返回空值 df[复合成本指数] df.apply(lambda x: calculate_composite_index(x, dynamic_weights), axis1) # # 可视化分析调整数据范围 # valid_data df[df.index dynamic_weights.index[0]] # 仅展示有效数据 fig plt.figure(figsize(18, 16)) gs GridSpec(3, 2, figurefig) # 1. 成本趋势分析 ax1 fig.add_subplot(gs[0, :]) valid_data[[仓储成本, 物流成本, 管理成本]].plot(axax1, markero, linewidth2) ax1.set_title(单箱成本分项趋势有效数据范围, fontsize14) ax1.set_ylabel(成本(元)) ax1.yaxis.set_major_formatter(mtick.FormatStrFormatter(%.1f)) ax1.grid(True, alpha0.3) ax1.legend(bbox_to_anchor(1.02, 1), locupper left) # 2. 权重动态变化 ax2 fig.add_subplot(gs[1, 0]) dynamic_weights.plot(axax2, style[o-, s--, D:], markersize6) ax2.set_title(动态权重变化趋势12个月滚动窗口, fontsize14) ax2.set_ylabel(权重系数) ax2.grid(True, alpha0.3) ax2.legend(bbox_to_anchor(1.02, 1), locupper left) # 3. 复合指数分析 ax3 fig.add_subplot(gs[1, 1]) valid_data[复合成本指数].plot(axax3, colorpurple, markers, linewidth2) ax3.axhline(valid_data[复合成本指数].mean(), colorr, linestyle--, labelf均值({valid_data[复合成本指数].mean():.2f})) ax3.set_title(复合成本指数动态变化, fontsize14) ax3.set_ylabel(指数值) ax3.grid(True, alpha0.3) ax3.legend() # 4. 波动率矩阵 ax4 fig.add_subplot(gs[2, 0]) volatility df.rolling(12).std().dropna() volatility.plot(axax4, colormapcoolwarm, linewidth2) ax4.set_title(12个月滚动波动率趋势, fontsize14) ax4.set_ylabel(波动率) ax4.grid(True, alpha0.3) # 5. 成本结构占比末月 ax5 fig.add_subplot(gs[2, 1]) last_month valid_data.iloc[-1][[仓储成本, 物流成本, 管理成本]] ax5.pie(last_month, labelslast_month.index, autopct%1.1f%%, colors[#4CAF50, #2196F3, #FF9800], startangle90, wedgepropsdict(width0.4)) ax5.set_title(f末月成本结构占比 ({last_month.name.strftime(%Y-%m)}), fontsize14) plt.tight_layout() plt.show() # # 数据报告输出 # print(动态权重示例最近3个月) print(dynamic_weights.tail(3).to_string()) print(\n复合成本指数描述统计) print(valid_data[复合成本指数].describe().to_string())运行结果