本文介绍如何使用 NumPy 解决一个常见的分配问题:根据商品的不同价格和库存数量,以及客户的订单数量,计算每个客户的平均购买价格。重点在于利用 NumPy 的 repeat 和 add.reduceat 函数,避免创建大型中间数组,从而提高计算效率。同时,也讨论了处理浮点数精度问题的一种方法。
问题描述假设你有一批商品,它们以不同的价格出售,并且有不同的库存数量。现在有一组客户,他们各自订购了不同数量的商品。你需要按照“先到先得”的原则,从价格最低的商品开始分配,计算每个客户的平均购买价格。
例如,你有以下数据:
- 客户订单 (orders): [21, 6, 3] (Mark 订购 21 个,Greg 订购 6 个,Paul 订购 3 个)
- 商品数量 (quantity): [16, 14] (有 16 个商品价格为 $30.5,14 个商品价格为 $35.5)
- 商品价格 (price): [30.5, 35.5]
目标是计算 Mark、Greg 和 Paul 的平均购买价格。
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) out = np.add.reduceat(np.repeat(price, quantity), np.r_[0, np.cumsum(orders)][:-1] ) / orders print(out) # 输出: [31.69047619 35.5 35.5 ]
代码解释:
- np.repeat(price, quantity): 此函数将 price 数组中的每个元素重复相应的 quantity 次数。例如,np.repeat([30.5, 35.5], [16, 14]) 将生成一个包含 16 个 30.5 和 14 个 35.5 的数组。
- np.cumsum(orders): 此函数计算 orders 数组的累积和。例如,np.cumsum([21, 6, 3]) 将生成 [21, 27, 30]。
- np.r_[0, np.cumsum(orders)][:-1]: 此表达式创建一个起始索引数组,用于 np.add.reduceat 函数。np.r_[0, np.cumsum(orders)] 将 0 添加到累积和数组的开头,然后 [:-1] 删除最后一个元素。因此,对于我们的示例,它将生成 [ 0, 21, 27]。
- np.add.reduceat(np.repeat(price, quantity), np.r_[0, np.cumsum(orders)][:-1]): 此函数沿着由 np.repeat 创建的数组,在指定的索引处进行求和。索引由 np.r_[0, np.cumsum(orders)][:-1] 提供。因此,它将计算 Mark (索引 0-20), Greg (索引 21-26) 和 Paul (索引 27-29) 的总价格。
- / orders: 最后,将总价格除以每个客户的订单数量,以获得平均价格。
由于浮点数的精度限制,计算平均价格时可能会出现一些小的误差。为了解决这个问题,可以确保平均价格乘以数量等于原始价格乘以数量的总和。
可以使用以下方法:
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) total_price = np.sum(price * quantity) out = np.add.reduceat(np.repeat(price, quantity), np.r_[0, np.cumsum(orders)][:-1] ) out = out / orders # 检查总价格是否一致 calculated_total_price = np.sum(out * orders) print(out) print(f"Total price should be: {total_price}") print(f"Calculated total price: {calculated_total_price}")
在实际应用中,如果需要更高的精度,可以考虑使用 decimal 模块。
总结本文介绍了如何使用 NumPy 高效地计算不同价格商品的客户平均购买价格。通过使用 np.repeat 和 np.add.reduceat 函数,可以避免创建大型中间数组,从而提高计算效率。此外,还讨论了处理浮点数精度问题的一种方法。这个方法可以应用于各种分配问题,例如库存管理、资源分配等。
以上就是使用 NumPy 高效计算不同价格商品的客户平均购买价格的详细内容,更多请关注知识资源分享宝库其它相关文章!
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。