当前位置:首页 > 文章列表 > 文章 > python教程 > NumPy优化库存分配与客户均价计算

NumPy优化库存分配与客户均价计算

2025-09-21 10:15:37 0浏览 收藏

今天golang学习网给大家带来了《NumPy优化库存分配与客户均价计算》,其中涉及到的知识点包括等等,无论你是小白还是老手,都适合看一看哦~有好的建议也欢迎大家在评论留言,若是看完有所收获,也希望大家能多多点赞支持呀!一起加油学习~

NumPy高效处理分层库存分配与客户平均价格计算

本文介绍如何使用NumPy高效解决多价库存按先进先出原则分配给客户订单的问题,并计算每位客户的平均购买价格。通过利用np.repeat和np.add.reduceat等向量化操作,避免了创建大型中间数组,显著提升了处理大规模数据的性能和内存效率。

1. 问题描述

在库存管理和订单处理场景中,我们经常会遇到需要将不同价格的商品分配给多个客户订单的情况。一个典型的场景是,商品以不同的批次或在不同时间点采购,导致其成本(或售价)存在差异。当客户下订单时,通常会遵循“先进先出”或“成本最低优先”的原则进行分配。我们的目标是,在满足客户订单需求的同时,计算出每位客户为其所购商品支付的平均价格。

假设我们有以下数据:

  • orders: 一个NumPy数组,表示每位客户的订单数量。例如 [21, 6, 3] 表示第一个客户需要21单位,第二个6单位,第三个3单位。
  • quantity: 一个NumPy数组,表示在特定价格下可用的商品数量。例如 [16, 14] 表示有16单位商品以某个价格出售,另有14单位商品以另一个价格出售。
  • price: 一个NumPy数组,与 quantity 对应,表示每批商品的单价。例如 [30.5, 35.5] 表示16单位商品单价为30.5,14单位商品单价为35.5。

关键约束和条件:

  1. 所有客户订单的总量 (np.sum(orders)) 始终等于所有可用商品的总量 (np.sum(quantity))。
  2. orders 数组通常按客户需求量降序排列(尽管这不是解决问题的严格要求,但反映了常见场景)。
  3. quantity 和 price 数组是关联的,且 price 数组按升序排列,这意味着我们总是优先分配价格最低的商品。

我们的任务是计算出每位客户的平均购买价格。

2. 低效的解决方案及其局限性

一种直观但低效的方法是创建一个巨大的数组,将所有商品的单价“展开”到这个数组中,然后根据客户订单的起始和结束索引来计算平均值。

import numpy as np

orders = np.array([21, 6, 3], dtype=np.int64)
quantity = np.array([16, 14], dtype=np.int64)
price = np.array([30.5, 35.5], dtype=np.double)

# 步骤1: 创建一个包含所有商品单价的“扁平化”数组
start = 0
total_supply_units = np.sum(quantity)
supply_prices_flat = np.zeros(total_supply_units, dtype=np.double)
for i, quant in enumerate(quantity):
    idx = start + quant
    supply_prices_flat[start:idx] = price[i]
    start = idx

print("扁平化商品价格数组:", supply_prices_flat)

# 步骤2: 根据客户订单计算平均价格
fin_avg_prices = []
current_pos = 0
for order_size in orders:
    idx = current_pos + order_size
    fin_avg_prices.append(np.mean(supply_prices_flat[current_pos:idx]))
    current_pos = idx

print("每位客户的平均价格 (低效方法):", fin_avg_prices)

输出示例:

扁平化商品价格数组: [30.5 30.5 30.5 30.5 30.5 30.5 30.5 30.5 30.5 30.5 30.5 30.5 30.5 30.5
 30.5 30.5 35.5 35.5 35.5 35.5 35.5 35.5 35.5 35.5 35.5 35.5 35.5 35.5
 35.5 35.5]
每位客户的平均价格 (低效方法): [31.69047619047619, 35.5, 35.5]

局限性: 当商品总数量 np.sum(quantity) 非常大时,supply_prices_flat 数组会变得极其庞大,导致严重的内存消耗和性能问题。这种方法在处理大规模数据集时是不可接受的。

3. 高效的NumPy解决方案

NumPy提供了强大的向量化操作,可以避免显式循环和创建大型中间数组。我们可以利用 np.repeat 和 np.add.reduceat 来高效地解决这个问题。

import numpy as np

orders = np.array([21, 6, 3], dtype=np.int64)
quantity = np.array([16, 14], dtype=np.int64)
price = np.array([30.5, 35.5], dtype=np.double)

# 步骤1: 使用 np.repeat 展开价格
# np.repeat(price, quantity) 会根据 quantity 中指定的次数重复 price 中的每个元素。
# 例如,如果 price=[P1, P2] 和 quantity=[Q1, Q2],结果将是 [P1, ..., P1 (Q1次), P2, ..., P2 (Q2次)]
repeated_prices = np.repeat(price, quantity)
# 结果: [30.5, ..., 30.5 (16次), 35.5, ..., 35.5 (14次)]

# 步骤2: 计算 reduceat 的索引
# np.cumsum(orders) 计算订单数量的累积和,用于确定每个客户订单在 repeated_prices 中的结束位置。
# np.r_[0, ...] 会在累积和数组前添加一个0,表示第一个客户订单的起始位置。
# [:-1] 移除最后一个元素,因为 reduceat 的索引是每个段的起始位置。
# 例如,orders=[21, 6, 3],cumsum=[21, 27, 30],indices=[0, 21, 27]
indices = np.r_[0, np.cumsum(orders)][:-1]

# 步骤3: 使用 np.add.reduceat 计算每个客户订单的总成本
# np.add.reduceat(array, indices) 会在指定索引处“切分” array,并对每个切分段进行求和。
# 这将直接计算出每个客户订单的总成本。
total_cost_per_customer = np.add.reduceat(repeated_prices, indices)

# 步骤4: 计算平均价格
# 将每个客户的总成本除以其订单数量,得到平均价格。
average_price_per_customer = total_cost_per_customer / orders

print("每位客户的平均价格 (高效NumPy方法):", average_price_per_customer)

输出:

每位客户的平均价格 (高效NumPy方法): [31.69047619 35.5        35.5       ]

4. 核心NumPy函数详解

4.1 numpy.repeat(a, repeats)

此函数用于重复数组 a 中的元素。repeats 可以是一个整数(所有元素重复相同次数),也可以是一个与 a 形状相同的数组(每个元素重复不同次数)。 在本例中,np.repeat(price, quantity) 的作用是根据 quantity 数组中每个对应的数量,将 price 数组中的价格值进行重复。这有效地模拟了将所有单独的商品单位及其价格平铺在一个数组中的过程,但它是通过NumPy的底层优化实现的,避免了显式创建巨大的中间列表。

4.2 numpy.add.reduceat(a, indices)

ufunc.reduceat 是一个非常强大的NumPy函数,它允许在指定索引处对数组进行“分段”操作。np.add.reduceat(array, indices) 的功能是:

  1. 在 indices 数组中指定的每个位置开始一个新的“段”。
  2. 对每个段内的元素执行 add 操作(即求和)。
  3. 返回一个数组,其中包含每个段的求和结果。

例如,如果 repeated_prices 是 [P1, P1, P1, P2, P2, P2] 且 indices 是 [0, 3]:

  • 第一个段从索引0开始,到索引3之前结束:[P1, P1, P1],求和为 3*P1。
  • 第二个段从索引3开始,到数组末尾结束:[P2, P2, P2],求和为 3*P2。 结果将是 [3*P1, 3*P2]。

在我们的解决方案中,indices 数组 np.r_[0, np.cumsum(orders)][:-1] 精确地标记了每个客户订单在 repeated_prices 数组中的起始位置。np.add.reduceat 随后对每个客户所购买的商品价格进行求和,直接得到每个客户的总成本。

5. 浮点数精度问题考量

在进行浮点数计算时,精度问题是普遍存在的。NumPy在内部使用IEEE 754标准来表示浮点数,这在大多数科学和工程计算中是足够的。对于本例中的平均价格计算: mean_prices * quantity == original_prices * quantities

由于浮点数的特性,直接比较两个浮点数是否“相等”通常是不可靠的。更好的做法是比较它们之间的绝对差是否小于一个很小的容忍值(epsilon)。

# 示例:验证总成本的准确性
# 计算高效方法得到的总成本
calculated_total_costs = average_price_per_customer * orders
print("高效方法计算的总成本:", calculated_total_costs)

# 原始的总供应成本
original_total_supply_cost = np.sum(price * quantity)
print("原始总供应成本:", original_total_supply_cost)

# 高效方法计算的所有客户总成本之和
sum_calculated_total_costs = np.sum(calculated_total_costs)
print("所有客户总成本之和:", sum_calculated_total_costs)

# 比较(考虑浮点精度)
tolerance = 1e-9 # 设置一个小的容忍值
if np.abs(sum_calculated_total_costs - original_total_supply_cost) < tolerance:
    print("总成本在浮点精度范围内一致。")
else:
    print("总成本存在显著差异。")

输出示例:

高效方法计算的总成本: [665.5 213.  106.5]
原始总供应成本: 985.0
所有客户总成本之和: 985.0
总成本在浮点精度范围内一致。

可以看到,在合理的浮点精度范围内,总成本是匹配的。对于极度严格的金融计算,可能需要考虑使用decimal模块或专门的定点数库,但对于大多数业务场景,NumPy的float64精度已足够。

6. 总结与注意事项

通过利用NumPy的np.repeat和np.add.reduceat函数,我们能够以高度优化的方式解决多价库存分配和客户平均价格计算问题。这种方法具有以下显著优点:

  • 内存效率高: 避免了创建可能非常庞大的中间数组,显著降低了内存消耗。
  • 计算速度快: 利用NumPy底层C语言实现,通过向量化操作极大地提升了计算速度,尤其适用于大规模数据集。
  • 代码简洁: 相比于基于循环的实现,代码更加紧凑和易读。

注意事项:

  • 数据预处理: 确保 price 数组与 quantity 数组严格对应,并且 price 数组已按升序排列,以保证“最低价优先”的分配原则。
  • 总量匹配: 务必确认 np.sum(orders) 和 np.sum(quantity) 相等,否则分配逻辑会出错。
  • 浮点数精度: 虽然NumPy通常表现良好,但在对结果进行精确比较或在金融等对精度要求极高的领域使用时,应注意浮点数的固有特性,并考虑使用适当的容忍值进行比较。

这种高效的NumPy方法是处理类似库存分配和成本计算问题的推荐实践,它充分体现了NumPy在数据处理方面的强大能力。

今天关于《NumPy优化库存分配与客户均价计算》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

HTML页面跳转方法及SEO建议HTML页面跳转方法及SEO建议
上一篇
HTML页面跳转方法及SEO建议
PerplexityAI如何实现语义搜索
下一篇
PerplexityAI如何实现语义搜索
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    499次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • PandaWiki开源知识库:AI大模型驱动,智能文档与AI创作、问答、搜索一体化平台
    PandaWiki开源知识库
    PandaWiki是一款AI大模型驱动的开源知识库搭建系统,助您快速构建产品/技术文档、FAQ、博客。提供AI创作、问答、搜索能力,支持富文本编辑、多格式导出,并可轻松集成与多来源内容导入。
    181次使用
  • SEO  AI Mermaid 流程图:自然语言生成,文本驱动可视化创作
    AI Mermaid流程图
    SEO AI Mermaid 流程图工具:基于 Mermaid 语法,AI 辅助,自然语言生成流程图,提升可视化创作效率,适用于开发者、产品经理、教育工作者。
    975次使用
  • 搜获客笔记生成器:小红书医美爆款内容AI创作神器
    搜获客【笔记生成器】
    搜获客笔记生成器,国内首个聚焦小红书医美垂类的AI文案工具。1500万爆款文案库,行业专属算法,助您高效创作合规、引流的医美笔记,提升运营效率,引爆小红书流量!
    996次使用
  • iTerms:一站式法律AI工作台,智能合同审查起草与法律问答专家
    iTerms
    iTerms是一款专业的一站式法律AI工作台,提供AI合同审查、AI合同起草及AI法律问答服务。通过智能问答、深度思考与联网检索,助您高效检索法律法规与司法判例,告别传统模板,实现合同一键起草与在线编辑,大幅提升法律事务处理效率。
    1010次使用
  • TokenPony:AI大模型API聚合平台,一站式接入,高效稳定高性价比
    TokenPony
    TokenPony是讯盟科技旗下的AI大模型聚合API平台。通过统一接口接入DeepSeek、Kimi、Qwen等主流模型,支持1024K超长上下文,实现零配置、免部署、极速响应与高性价比的AI应用开发,助力专业用户轻松构建智能服务。
    1079次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码