
本文介绍如何基于商品组(如 shoes、shirt)内已知的最小/最大尺寸顺序,对 length、width、height、volume 等连续型字段进行线性插值填充,支持混合型尺寸(如 's'/'m' 和 '1'/'2'),并具备面向新 skugroup 的可扩展性。
在电商或仓储系统中,SKU 尺寸常以非数值形式(如 's', 'xl', '3xl')或数值形式(如 '1', '5')表示,而其对应物理属性(长、宽、高、体积)往往呈近似线性关系。当部分 SKU 的这些属性缺失时,若简单用均值或前向填充,会破坏尺寸-属性间的单调性;更优解是按尺寸语义顺序进行线性插值——即先定义尺寸的逻辑序,再在该序下对数值列做等距映射。
核心思路是:将 size 列转换为 有序分类类型(CategoricalDtype),使其支持 sort_values() 和 interpolate() 的天然协同。Pandas 的 interpolate() 在分组后对排序数据调用时,会自动基于索引位置(即尺寸顺序)执行线性插值,完美替代手动 np.linspace() + 手动对齐的易错逻辑。
以下为完整、可扩展的实现方案:
import pandas as pd
import numpy as np
# 示例数据(含 NaN)
data_wm = {
'sku': [6124, 7343, 7981, 5761, 1570, 7223, 4107, 8187, 4653, 1802, 4079],
'skugroup': ['shoes', 'shoes', 'shoes', 'shoes', 'shoes', 'shoes', 'shirt', 'shirt', 'shirt', 'shirt', 'shirt'],
'size': ['s', 'm', 'l', 'xl', '2xl', '3xl', '1', '2', '3', '4', '5'],
'length': [1.5, np.nan, np.nan, np.nan, np.nan, 6, 1, np.nan, np.nan, np.nan, 4],
'width': [2, np.nan, np.nan, np.nan, np.nan, 8, 2, np.nan, np.nan, np.nan, 5],
'height': [2, np.nan, np.nan, np.nan, np.nan, 3, 3, np.nan, np.nan, np.nan, 6],
'volume': [6, np.nan, np.nan, np.nan, np.nan, 144, 6, np.nan, np.nan, np.nan, 120]
}
df = pd.DataFrame(data_wm)
# ✅ 定义全局尺寸顺序(支持未来新增 skugroup,如 'pants': ['28', '29', ..., '42'])
txt_sizes = ['xs', 's', 'm', 'l', 'xl', '2xl', '3xl', '4xl', '5xl']
num_sizes = [str(i) for i in range(1, 21)] # 覆盖常见数字尺寸
all_sizes = txt_sizes + num_sizes
# 创建有序分类类型(关键!)
size_dtype = pd.CategoricalDtype(all_sizes, ordered=True)
# ✅ 核心处理:按 skugroup 分组 → 按 size 排序 → 对数值列插值
numeric_cols = ['length', 'width', 'height', 'volume']
df[numeric_cols] = (
df.astype({'size': size_dtype}) # 强制转换为有序分类
.sort_values(['skugroup', 'size']) # 先按组、再按尺寸顺序排序
.groupby('skugroup', sort=False)[numeric_cols]
.apply(lambda x: x.interpolate(method='linear')) # 组内线性插值
.reset_index(drop=True) # 保持原始索引对齐(重要!)
.reindex(df.index) # 确保结果与原 df 行序一致
)
print(df.round(2))✅ 输出说明:shoes 组中 's'→'3xl' 共 6 个尺寸,length 从 1.5 线性增至 6.0,步长 0.9;shirt 组 '1'→'5' 同理,volume 从 6 增至 120,严格满足线性关系。
关键优势与注意事项:
- 可扩展性强:只需在 all_sizes 列表中追加新尺寸(如 'xxs', '6', 'waist32'),无需修改主逻辑;新增 skugroup(如 'pants')会自动被 groupby 处理。
- 健壮性高:interpolate() 自动跳过首尾 NaN(仅对中间缺失值插值),且不依赖 fillna() 的索引对齐风险。
-
避免陷阱:
- ❌ 不要直接对 size 字符串排序('10'
- ❌ 不要手动 np.linspace() 后用 fillna() —— 易因索引错位导致值填到错误行;
- ✅ 务必使用 reset_index(drop=True) + reindex() 保证插值结果严格落回原始位置。
此方法将“尺寸语义顺序”与“物理属性线性变化”解耦建模,是处理多品类 SKU 尺寸映射问题的工业级实践方案。










