在架率多仓SKU矩阵计算 — 多仓×多SKU有货率精确口径与缺货金额加权
Skill-On-Shelf-Availability-SKU-Matrix · 04-供应链
causalexperimentpricing供应链与补货定价与利润WF-A 智能补货WF-F 动态定价WF-I 智能体工程
年化 ROI1万元
实现难度⭐⭐☆☆☆
业务视角
适用角色供应链负责人 · 采购负责人 · CEO / 运营 VP
适用平台Amazon FBA · 海外仓 · 多国仓位(美/欧/日)
什么情况下用库存周转率低,资金压在海外仓出不来;SKU 断货紧急空运,物流成本吃掉毛利;多仓库存分布不均
成功是什么样的库存周转天数从 90 天降到 60 天,断货率 <3%,海外仓综合成本降低 15-25%
业务痛点
1. 解决的问题
多仓运营面临"虚报在架率掩盖分仓缺货"——仓×SKU矩阵口径比单SKU口径严格2-5pp,A类爆品OSA提升至99%年化增量销售15万元
2. 核心算法逻辑
在架率(OnShelf Availability, OSA) 在多仓场景下不是简单的"有没有货",而是一个 仓×SKU矩阵 的计算。陈凤霞书中给出了精确的矩阵口径,这是多数企业算错的核心原因。
3. 业务应用场景
场景A:多仓母婴平台OSA矩阵监控 - 业务问题:品牌在京东/天猫/自建仓等20个仓运营500+ SKU,"总体有货"但部分区域缺货导致跨仓发货,时效变差 - 数据要求:每个仓×每个SKU的实时库存量 + 日均销量 - 预期产出: - 整体OSA = 94.2%(矩阵口径,单仓口径虚高98.5%) - A类爆品(30个SKU)在西部仓缺货最严重(OSA 87%) - 缺货金额率 = 2.1%(A类产品单价高,金额影响大) - 业务价值:针对性补货西部仓,A类产品OSA提升至98%,本地订单达成率提升6pp
**场景B:跨境FBA多国仓OSA监控** - **业务问题**:美国/德国/英国FBA三个市场同时运营,某SKU在德国FBA缺货但美国有货,是否跨国调拨? - **数据要求**:各国FBA库存 + 日均销量 + 跨国调拨成本 - **预期产出**:德国FBA 5个SKU OSA = 0%(完全缺货),调拨成本 vs 空运补货成本对比 - **业务价值**:系统化多国OSA监控,提前7天预警,减少FBA断货事件50%
4. 输入数据要求
请查看原始代码模板获取输入规格。
5. 输出结果
请查看原始代码模板获取输出规格。
6. 业务价值 / ROI
- ROI预估:多仓OSA从94%提升至97%(矩阵口径)≈ 减少缺货率3pp → 年化减少缺货销售损失约15-25万元(按日均GMV 5万估算);A类爆品OSA每提升1pp约贡献年增量销售4-8万元
- 实施难度:⭐⭐☆☆☆(需要WMS库存数据 + 日销数据联动,主要是口径统一工作)
- 优先级评分:⭐⭐⭐⭐⭐(陈凤霞书明确:矩阵口径是"真实有货率",单SKU口径会系统性高估2-5pp)
- 评估依据:京东研究:FDC满足率提升1pp可节省库存持有成本4451万元(规模效应),中小品牌同比例约10-30万元
7. 代码模板
代码块数量:1 · 路径:未检测到
"""
在架率多仓SKU矩阵计算体系
功能:多仓×SKU矩阵OSA / 金额加权缺货率 / DOS预警 / 分品类分析 / 补货优先级
输入:各仓库各SKU的库存量 + 日均销量 + 单价
输出:OSA矩阵报告 + 缺货预警 + 补货优先级列表
"""
import numpy as np
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
def generate_multi_warehouse_inventory(n_skus=50, n_warehouses=12, seed=42):
"""生成多仓×多SKU库存数据"""
np.random.seed(seed)
warehouses = [f'WH-{i:02d}' for i in range(1, n_warehouses + 1)]
warehouse_regions = {f'WH-{i:02d}': region for i, region in enumerate(
['华东', '华东', '华北', '华北', '华南', '华南', '华西', '华西',
'US-East', 'US-West', 'DE', 'GB'], 1)}
abc_classes = np.random.choice(['A', 'B', 'C', 'D', 'E'],
size=n_skus, p=[0.06, 0.14, 0.30, 0.30, 0.20])
unit_prices = {'A': 180, 'B': 120, 'C': 60, 'D': 25, 'E': 10}
base_daily_sales = {'A': 25, 'B': 12, 'C': 5, 'D': 2, 'E': 0.5}
records = []
for sku_idx in range(n_skus):
sku = f'SKU-{sku_idx+1:03d}'
abc = abc_classes[sku_idx]
price = unit_prices[abc] * np.random.uniform(0.7, 1.3)
daily_sales_base = base_daily_sales[abc] * np.random.uniform(0.5, 2.0)
for wh in warehouses:
# 模拟缺货情况:A类缺货较少,CDE类缺货较多
oos_prob = {'A': 0.03, 'B': 0.06, 'C': 0.10, 'D': 0.15, 'E': 0.20}[abc]
is_oos = np.random.random() < oos_prob
if is_oos:
inventory = 0
else:
# 库存量(DOS约10-40天)
inventory = int(daily_sales_base * np.random.uniform(10, 40) + np.random.randint(0, 50))
# 仓库区域的日均销量(权重不同)
region_factor = {'华东': 1.4, '华北': 1.2, '华南': 1.1,
'华西': 0.6, 'US-East': 1.0, 'US-West': 0.8,
'DE': 0.4, 'GB': 0.3}.get(warehouse_regions[wh], 1.0)
daily_sales = max(0.1, daily_sales_base * region_factor * np.random.uniform(0.7, 1.3))
dos = inventory / daily_sales if daily_sales > 0 else 999
records.append({
'sku_id': sku,
'warehouse': wh,
'region': warehouse_regions[wh],
'abc_class': abc,
'unit_price': round(price, 2),
'inventory': inventory,
'daily_sales': round(daily_sales, 2),8. 论文来源
- 2308.10293