Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何获得其所属列表的加权平均值';的权重受Python 3.6中的变量限制_Python_List_Numpy_Average_Weighted - Fatal编程技术网

如何获得其所属列表的加权平均值';的权重受Python 3.6中的变量限制

如何获得其所属列表的加权平均值';的权重受Python 3.6中的变量限制,python,list,numpy,average,weighted,Python,List,Numpy,Average,Weighted,我希望这个标题有意义。我想得到的是鞋子的加权平均价格,这些鞋子的价格不同,数量也不同。例如,我有: list_prices = [12,12.7,13.5,14.3] list_amounts = [85,100,30,54] BuyAmount = x 我想知道我的加权平均价格,以及如果我买x数量的鞋子,我每只鞋子支付的最高价格(假设我想先买最便宜的) 这就是我现在拥有的(我使用numpy): 这段代码可以工作,但可能过于复杂和扩展。特别是因为我想能够处理20多个项目的金额和价格清单 更好的

我希望这个标题有意义。我想得到的是鞋子的加权平均价格,这些鞋子的价格不同,数量也不同。例如,我有:

list_prices = [12,12.7,13.5,14.3]
list_amounts = [85,100,30,54]
BuyAmount = x
我想知道我的加权平均价格,以及如果我买x数量的鞋子,我每只鞋子支付的最高价格(假设我想先买最便宜的)

这就是我现在拥有的(我使用numpy):

这段代码可以工作,但可能过于复杂和扩展。特别是因为我想能够处理20多个项目的金额和价格清单


更好的方法是什么?

这里有一个通用的矢量化解决方案,使用
cumsum
替换切片求和,并使用
argmax
获取适当的索引,用于设置那些
IF case
操作的切片限制-

# Use cumsum to replace sliced summations - Basically all those 
# `list_amounts[0]`, `sum(list_amounts[0: 2]))`, `sum(list_amounts[0: 3])`, etc.
c = np.cumsum(list_amounts)

# Use argmax to decide the slicing limits for the intended slicing operations.
# So, this would replace the last number in the slices - 
# list_prices[0: 2], list_prices[0: 3], etc.
idx = (c >= BuyAmount).argmax()

# Use the slicing limit to get the slice off list_prices needed as the first
# input to numpy.average
l = list_prices[:idx+1]

# This step gets us the weights. Now, in the weights we have two parts. E.g.
# for the third-IF we have : 
# [list_amounts[0],list_amounts[1],BuyAmount - (sum(list_amounts[0: 2]))]
# Here, we would slice off list_amounts limited by `idx`.
# The second part is sliced summation limited by `idx` again.
w = np.r_[list_amounts[:idx], BuyAmount - c[idx-1]]

# Finally, plug-in the two inputs to np.average and get avgprice output.
avgprice = np.average(l,weights=w)

# Get idx element off list_prices as the highprice output.
highprice = list_prices[idx]
我们可以进一步优化以删除连接步骤(使用
np.r
)并获得
avgprice
,如下所示-

slice1_sum = np.multiply(list_prices[:idx], list_amounts[:idx]).sum()
        # or np.dot(list_prices[:idx], list_amounts[:idx])
slice2_sum = list_prices[idx]*(BuyAmount - c[idx-1])
weight_sum = np.sum(list_amounts[:idx]) + BuyAmount - c[idx-1]
avgprice = (slice1_sum+slice2_sum)/weight_sum

您的确是对的,您的代码缺乏灵活性。但在我看来,你是从一个有效的角度来看待这个问题,但还不够全面

换句话说,您的解决方案实现了这一想法:“让我先检查一下——给定每个价格的可用数量(我将其完美地排列在一个数组中)——我必须从哪些不同的卖家那里购买,然后进行所有计算。”

一个更灵活的想法可以是:“让我开始尽可能多地从更便宜的商品中购买。当我的订单完成时,我会停止,并一步一步地计算。”。这意味着您要构建一个迭代代码,一步一步累积总花费量,并在完成计算后计算每件产品的平均价格和最高价格(即在您的订单列表中最后访问的价格)

要将此想法转化为代码:

list_prices = [12,12.7,13.5,14.3]
list_amounts = [85,100,30,54]
BuyAmount = x

remaining = BuyAmount
spent_total = 0
current_seller = -1 # since we increment it right away 

while(remaining): # inherently means remaining > 0
    current_seller += 1
    # in case we cannot fulfill the order
    if current_seller >= len(list_prices):
        # since we need it later we have to restore the value
        current_seller -= 1
        break
    # we want either as many as available or just enough to complete 
    # BuyAmount
    buying = min([list_amounts[current_seller], remaining])
    # update remaining
    remaining -= buying
    # update total
    spent_total += buying * list_prices[current_seller]

# if we got here we have no more remaining or no more stock to buy

# average price
avgprice = spent_total / (BuyAmount - remaining) 

# max price - since the list is ordered -
highprice = list_prices[current_seller]

print(avgprice)
print(highprice)

大多数情况下,使用numpy比普通python效率更高,但代码看起来往往晦涩难懂:您能添加一些注释和解释吗?@FabioVeronese补充道。非常感谢您的帮助。我不得不做很多研究,因为我不熟悉cumsum、argmax和np\r。cumsum真的大大缩短了代码的长度哈哈,这正是你真正需要的。您如何找到amountindex,其中的金额填充了订单,这也是非常方便的,并且最终您拥有了一个非常高效的代码!我有一个问题,为什么删除连接步骤的优化是一件好事?再次感谢您的帮助,学到了很多@连接需要额外的内存来存储连接的数组。通过将其替换为后一部分所示的原位操作,我们节省了内存,并有望提高性能效率。非常感谢您的回复。很高兴听到我的思路是正确的。这就是说,我甚至没有想过在一个遥远的地方编程,它只需要看看相关的金额。我像这样实现了它,它工作了!我还学到了很多关于你的代码以及它比我的代码更高效的方法:)再次感谢
list_prices = [12,12.7,13.5,14.3]
list_amounts = [85,100,30,54]
BuyAmount = x

remaining = BuyAmount
spent_total = 0
current_seller = -1 # since we increment it right away 

while(remaining): # inherently means remaining > 0
    current_seller += 1
    # in case we cannot fulfill the order
    if current_seller >= len(list_prices):
        # since we need it later we have to restore the value
        current_seller -= 1
        break
    # we want either as many as available or just enough to complete 
    # BuyAmount
    buying = min([list_amounts[current_seller], remaining])
    # update remaining
    remaining -= buying
    # update total
    spent_total += buying * list_prices[current_seller]

# if we got here we have no more remaining or no more stock to buy

# average price
avgprice = spent_total / (BuyAmount - remaining) 

# max price - since the list is ordered -
highprice = list_prices[current_seller]

print(avgprice)
print(highprice)