You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新旧门店相似度匹配及销售额均值计算:无循环实现与算法优化

门店相似度匹配与销售额预测优化方案

数据集与需求

现有数据集

新门店数据集:

import pandas as pd
from sklearn.preprocessing import MinMaxScaler
import numpy as np

stores_new = pd.DataFrame({
    'id_store': [11, 12, 13], 
    'size': [5, 5, 6], 
    'location': ['aaa', 'bbb', 'aaa']
})

旧门店数据集:

stores_old = pd.DataFrame({
    'id_store': [1, 2, 3, 4, 5],
    'size': [4, 5, 5, 3, 7],
    'location': ['aaa', 'bbb', 'aaa', 'ccc', 'bbb'],
    'sales': [5555, 11111, 6666, 5555, 2222]
})

核心需求

为每个新门店匹配3家最相似的旧门店,并计算这些旧门店的销售额均值。

当前相似度计算逻辑

现有代码通过以下方式计算相似度:

  • 数值变量:经MinMaxScaler缩放后,计算绝对差之和(得分越低越相似)
  • 分类变量:不匹配时计0.5,匹配计0,求和得到分类相似度得分
def numerical_data(point, data):
    count = [(sum(abs(a-b) for a, b in zip(point, sublist))) for sublist in data.values]
    return count

def categorical_data(point, data):
    count = [(sum(0.5 for a, b in zip(point, sublist) if a != b)) for sublist in data.values]
    return count

待解决问题

  1. 如何不使用循环实现当前逻辑?旧门店数据集有上千条记录、15个变量,循环方式(如iterrows)效率低下;
  2. 针对数值与分类混合数据,是否有更优的相似度计算算法?

解决方案

问题1:无循环的向量化实现

利用Pandas和Numpy的向量化运算(广播机制)替代循环,大幅提升效率:

步骤1:分离变量并预处理

# 分离数值和分类变量
num_cols = ['size']
cat_cols = ['location']

# 对数值变量做MinMax缩放
scaler = MinMaxScaler()
stores_old_num_scaled = scaler.fit_transform(stores_old[num_cols])
stores_new_num_scaled = scaler.transform(stores_new[num_cols])

步骤2:向量化计算相似度得分

# 数值变量:广播计算每个新门店与所有旧门店的绝对差之和
num_diff = np.abs(stores_new_num_scaled[:, np.newaxis, :] - stores_old_num_scaled).sum(axis=2)

# 分类变量:计算每个新门店与旧门店的不匹配项得分(不匹配计0.5)
cat_diff = (stores_new[cat_cols].values[:, np.newaxis, :] != stores_old[cat_cols].values).astype(float).sum(axis=2) * 0.5

# 总相似度得分(得分越低,相似度越高)
total_diff = num_diff + cat_diff

步骤3:匹配Top3相似门店并计算销售额均值

# 对每个新门店的得分排序,取前3个旧门店的索引
top3_indices = np.argsort(total_diff, axis=1)[:, :3]

# 提取对应销售额并计算均值
sales_means = stores_old['sales'].values[top3_indices].mean(axis=1)

# 生成结果
stores_new_sales = pd.DataFrame({
    'id_store': stores_new['id_store'],
    'sales': np.round(sales_means, 2)
})

print(stores_new_sales)

输出结果与期望一致:

id_store    sales
0        11  5925.33
1        12  2962.67
2        13  5925.33

问题2:更优的相似度计算算法

针对混合类型数据,推荐以下更专业的方案:

1. 数值变量优化

  • 欧氏距离:替代曼哈顿距离(绝对差之和),适合关注变量间平方差异的场景,公式为$\sqrt{\sum(a-b)^2}$
  • 加权距离:为业务上更重要的变量赋予更高权重(如size权重设为2,location权重设为1)
  • 标准化方式调整:若数值变量服从正态分布,用StandardScaler替代MinMaxScaler,避免极值影响

2. 分类变量优化

  • Gower距离:专门为混合类型数据设计的相似度算法,自动区分数值/分类变量:
    • 数值变量:计算标准化后的相对距离
    • 分类变量:匹配则为0,不匹配则为1
      可以通过gower库快速实现(需先安装:pip install gower),示例:
    import gower
    
    # 计算所有新门店与旧门店的Gower距离矩阵
    gower_dist = gower.gower_matrix(stores_new[num_cols+cat_cols], stores_old[num_cols+cat_cols])
    
    # 取Top3相似门店计算销售额均值
    top3_indices_gower = np.argsort(gower_dist, axis=1)[:, :3]
    sales_means_gower = stores_old['sales'].values[top3_indices_gower].mean(axis=1)
    
  • 独热编码+余弦相似度:对分类变量做独热编码后,将所有变量转为数值型,计算余弦相似度(适合分类变量基数较小的场景)

内容的提问来源于stack exchange,提问作者Veracious

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 11:20:37