numpy 如何将与价目表相关的产品数量表分配到客户订单表中

polhcujo  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(98)

我有一个分配问题-我有不同价格的产品供应,我需要按照先到先得的原则卖给人们,从最便宜的价格开始。
我有4个不同的列表/numpy数组:

people = ['mark', 'greg', 'paul']       #This list is not needed, just for easier understanding
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)

字符串
订单的总和总是等于数量的总和。列表人员和订单是“连接”的,并根据降序排序:Mark想要购买21的数量,Greg想要购买6,Paul想要购买3。列表数量和价格也是“连接”的,并根据价格升序排序:有16个供应价格为30.5美元,14个供应价格为35.5美元。
计算每个买家的平均价格的最佳方法是什么?
一个简单的解决方案是:

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)

start = 0
supply = np.zeros((np.sum(quantity)), dtype=np.double)
for i, quant in enumerate(quantity):
    idx = start + quant
    supply[start:idx] = price[i]
    start = idx

print(supply)
# [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]

fin = []
start = 0
for order in orders:
    idx = start + order
    fin.append(np.mean(supply[start:idx]))
    start = idx

print(fin)
# [31.69047619047619, 35.5, 35.5]


但这是可怕的,因为供应数组可能会变得非常大。我知道一定有一个很好的方法来处理numpy函数/索引,但我不知道如何做到这一点。最好的方法是什么?如果有人有任何关于如何处理浮点精度问题的提示,那也会很感激。(如何始终使:mean_prices * quantity == original_prices * quantities)

daolsyd0

daolsyd01#

您可以使用repeat扩展价格,并使用add.reduceat对每个块求和,然后通过除以项目数获得平均值:

out = np.add.reduceat(np.repeat(price, quantity),
                      np.r_[0, np.cumsum(orders)][:-1]
                     ) / orders

字符串
输出量:

array([31.69047619, 35.5       , 35.5       ])

u59ebvdq

u59ebvdq2#

您可以从两个列表中减少ordersquantity之间的最小值,并删除零和更小的值,直到订单为空

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)

original_orders = orders.copy()

fin = np.zeros(len(orders))

while orders.size > 0:
    val = min(orders[0], quantity[0])
    orders[0] -= val
    quantity[0] -= val
    fin[-len(orders)] += price[-len(quantity)] * val
    orders = orders[orders > 0]
    quantity = quantity[quantity > 0]

fin = np.around(fin / original_orders, 2)

print(fin) # [31.69 35.5  35.5 ]
# or if you want a list
print(fin.tolist()) # [31.69, 35.5, 35.5]

字符串

相关问题