gpt4 book ai didi

python - Numpy:需要最有效的方法来处理 1D ndarray 中的选择元素,使用 2D ndarray 的映射,以输出 1D 平均 ndarray

转载 作者:太空宇宙 更新时间:2023-11-03 14:38:35 29 4
gpt4 key购买 nike

首先,这不是作业问题;而是作业问题。它是与我的工作相关的实际问题的抽象。我真的很感谢所有的意见!

我需要运行类似于下面的计算,按顺序运行数万次,它的计算时间显着影响我的模拟的总持续时间:

在这个抽象中:

  • 我有 60,000 个小部件以及每个小部件类别的一系列价格,“widget_prices”。
  • 我有一个 2D 映射 price_mapping,其中每 30,000 行对应于购买一篮子这些小部件,并且每个60,000 列对应于与以下内容一致的小部件类widget_prices 的索引。 Bool 值为 false 表示该小部件不在购物篮中,值为 true 表示该小部件位于购物篮中。
  • 我想生成一个数组,其中计算出小部件的平均价格30,000 个篮子中的每一个(对于 price_mapping 的每行)

显示了数据结构的图示here

下面是我编写的一些代码,测试了我能想到的 3 种不同方法。第一个包括 np.mean 和常规 Python 列表理解,第二个包括 np.average、np.tile。和逐元素矩阵乘法,第三个包括 np.ma、np.tile 和 np.mean。

import numpy as np
import time

number_of_widgets = 60000
number_of_orders = 30000

widget_prices = np.random.uniform(0, 1, number_of_widgets)
price_mapping = np.random.randint(2, size=(number_of_orders, number_of_widgets), dtype=bool)

# method 1, using np.mean and a python list comprehension
start = time.time()
mean_price_array_1 = np.array([np.mean(widget_prices[price_mapping[i, :]]) for i in range(number_of_orders)])
end = time.time()
print('method 1 took ' + str(end - start) + ' seconds')

# method 2, using np.average, np.tile, and element-wise matrix multiplication
start = time.time()
mean_price_array_2 = np.average(np.tile(widget_prices, (number_of_orders, 1)) * price_mapping, weights=price_mapping,
axis=1)
end = time.time()
print('method 2 took ' + str(end - start) + ' seconds')

# method 3, using np.ma (masked array), np.tile, and np.mean
start = time.time()
mean_price_array_3 = np.ma.array(np.tile(widget_prices, (number_of_orders, 1)), mask=~price_mapping).mean(axis=1)
end = time.time()
print('method 3 took ' + str(end - start) + ' seconds')

这些是我得到的结果:

method 1 took 10.472509145736694 seconds
method 2 took 28.92689061164856 seconds
method 3 took 18.18838620185852 second

第一个具有最快的计算时间,但对于我的需求来说仍然太慢。

有什么方法可以提高列表理解吗?

提前谢谢您!!

-S

最佳答案

对于 price_mapping 作为 bool 掩码,每次迭代都会选择 widget_prices 中的元素,我们可以简单地使用 matrix-multiplicationnp.dot对于矢量化解决方案并希望更快的方式,就像这样 -

price_mapping.dot(widget_prices)/price_mapping.sum(1)

计算每行非零值的更快方法是使用 np.count_nonzero 。因此,另一种方法是 -

price_mapping.dot(widget_prices)/np.count_nonzero(price_mapping, axis=1)

关于python - Numpy:需要最有效的方法来处理 1D ndarray 中的选择元素,使用 2D ndarray 的映射,以输出 1D 平均 ndarray,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46722587/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com