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

Python中求解商品单价及处理订单异常值问题求助

解决np.linalg.lstsq维度不匹配的问题

我来帮你搞定这个问题,你遇到的LinAlgError: Incompatible dimensions本质是因为你构建的矩阵完全不符合最小二乘法的要求——你把商品名称(字符串)和数量混在了一个数组里,而且单个订单的矩阵形状也不对。咱们一步步来修正:

问题根源分析

np.linalg.lstsq要求的输入是:

  • 第一个参数X:是一个(n_samples, n_features)的数值型矩阵,每一行代表一个样本(这里就是一个订单),每一列代表一个特征(这里是对应商品的订购数量)
  • 第二个参数y:是一个(n_samples,)的数值型向量,对应每个样本的目标值(这里是订单总价)

你之前的操作把商品名称和数量拼成了(4,2)的字符串数组,这既不是数值矩阵,形状也不满足lstsq的要求,自然会报错。

正确的解决方案

我们需要把所有订单数据转换成符合要求的数值矩阵和目标向量,步骤如下:

1. 提取所有唯一商品名称

首先从所有订单里找出所有的商品,确定我们要求解的单价变量:

import numpy as np
from collections import defaultdict

# 你的示例数据
order_data = {
    1215.5: [('Shrimp', 10), ('Fish&Chips', 6), ('Salmon', 8), ('Pasta', 5)],
    1230.0: [('Shrimp', 10), ('Salmon', 10), ('Fish&Chips', 8)],
    1234.0: [('Salmon', 9), ('Fish&Chips', 3), ('Pasta', 8), ('Shrimp', 10)],
    1292.5: [('Pasta', 7), ('Salmon', 9), ('Fish&Chips', 7), ('Shrimp', 9)],
    1301.5: [('Pasta', 5), ('Shrimp', 9), ('Salmon', 8), ('Fish&Chips', 10)],
    1314.5: [('Shrimp', 10), ('Pasta', 5), ('Fish&Chips', 10), ('Salmon', 7)],
    1343.5: [('Shrimp', 8), ('Fish&Chips', 10), ('Salmon', 9), ('Pasta', 7)]
}

# 获取所有唯一商品
all_products = list({product for order in order_data.values() for product, _ in order})
n_products = len(all_products)
n_orders = len(order_data)

2. 构建系数矩阵X和目标向量y

对每个订单,按照all_products的顺序,生成对应商品的数量数组(没有订购的商品数量为0),同时收集订单总价:

# 初始化矩阵和向量
X = np.zeros((n_orders, n_products), dtype=np.float64)
y = np.zeros(n_orders, dtype=np.float64)

for i, (total_price, items) in enumerate(order_data.items()):
    y[i] = total_price
    # 把当前订单的商品数量映射到X的对应列
    product_count = defaultdict(int)
    for product, count in items:
        product_count[product] = count
    # 填充X的第i行
    for j, product in enumerate(all_products):
        X[i, j] = product_count[product]

现在X的形状是(7,4)(7个订单,4种商品),y的形状是(7,),完全符合lstsq的要求。

3. 调用最小二乘法求解单价

现在就可以正常调用np.linalg.lstsq了:

# 求解,rcond=None是为了适配新版本numpy的默认设置
prices, residuals, rank, singular_values = np.linalg.lstsq(X, y, rcond=None)

# 把结果和商品对应起来
product_prices = dict(zip(all_products, prices))
print("各商品单价:")
for product, price in product_prices.items():
    print(f"{product}: {price:.2f}")

补充:如果只用单个订单怎么办?

如果你只想用单个订单(比如总价1234.0的那条)求解,那其实不需要最小二乘法,直接解线性方程组就行:

# 取目标订单
single_order_total = 1234.0
single_order_items = order_data[single_order_total]

# 构建单个订单的系数矩阵(形状(1,4))和目标值
single_X = np.zeros((1, n_products))
single_y = np.array([single_order_total])
for j, product in enumerate(all_products):
    for p, cnt in single_order_items:
        if p == product:
            single_X[0, j] = cnt
            break

# 解线性方程组
single_prices = np.linalg.solve(single_X, single_y)
print("单个订单求解的单价:", dict(zip(all_products, single_prices)))

不过更推荐用多个订单做最小二乘,这样可以抵消部分异常订单的影响,得到更准确的单价,也方便后续识别异常值(比如残差过大的订单)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:08:41