【问题标题】:More Efficient For-Loop Calculation?更高效的 For 循环计算?
【发布时间】:2022-11-10 23:33:36
【问题描述】:

有没有更有效的方法来编写以下内容?我目前有这个设置来使用for循环进行计算,按照这个速度,编译需要几天时间。

我按产品类型(586 种类型)和邮政编码(892 个唯一邮政编码)每周(52 周)预测 6 年内的需求。 rand 数组是从正态分布中提取的每年的参数需求份额,维度为 [#weeks/#types/#zips x 6]。需求增长数组是每年的年需求。

我最终需要生成一个具有以下内容的数据框:
年份 |年度一周 |产品 |邮政编码 |数量

这是我目前拥有的

demand_growth = [10,15,20,23,26,30]
rand_week_total = np.random.rand(52,6)
rand_product_total = np.random.rand(586,6)
rand_zipcode_total = np.random.rand(892,6)

forecast_year = []
forecast_week = []
forecast_product = []
forecast_ZIP = []
forecast_qty = []

for i in range(len(years)):
    for j in range(len(week)):
        for k in range(len(product)):
            for l in range(len(zipcode)):
                a = np.rint(demand_growth[i]*rand_week_total[j,i]*rand_product_total[k,i]*rand_zipcode_total[l,i])
                if a !=0:
                    forecast_year.append(years[i])
                    forecast_week.append(week[j])
                    forecast_product.append(product[k])
                    forecast_ZIP.append(zipcode[l])
                    forecast_qty.append(a)

''' 已编辑:包含被相乘的数组的示例

任何建议将不胜感激!

【问题讨论】:

  • 我不确定您设置 a 的行中的某些变量/可迭代对象被定义为什么,但在我看来,这对于 Numpy 和/或矩阵乘法来说是一个成熟的问题。这里的主要好处是并行化操作(Numpy 会自动为你做)。
  • 我完全同意@AndW,为了减少你的 for 循环,你需要在 rand_week/product/zipcode_total 之间引入一些矩阵乘法。如果可能,如果您的大部分数据无用,请尝试使用一些稀疏矩阵来加快您的流程
  • 我该怎么做?引入带有周/产品/邮政编码的 3d 矩阵,然后引用该位置?但是我该如何记录每个单元格的标签(例如第 1 年,第 2 周,产品 B,邮政编码 29681)?
  • 此外,编辑以包含 rand_total 数组维度的示例

标签: python numpy for-loop


【解决方案1】:

我认为你可以做的不仅仅是学习如何使用数组和/或线程。目前,我得到的最好的结果是快了 3 倍。我使用较低的界限来不为此过夜。

import numpy as np
import timeit

def f1():
    demand_growth = np.array([10,15,20,23,26,30])
    rand_week_total = np.random.rand(52,6)
    rand_product_total = np.random.rand(23,6)
    rand_zipcode_total = np.random.rand(43,6)

    forecast_year = []
    forecast_week = []
    forecast_product = []
    forecast_ZIP = []
    forecast_qty = []

    years = np.array(range(2015, 2020))
    weeks = np.array(range(0, 52))
    product = np.array(range(0, 23))
    zipcode = np.array(range(0, 43))

    for i in range(len(years)):
        for j in range(len(weeks)):
            for k in range(len(product)):
                for l in range(len(zipcode)):
                    a = np.rint(demand_growth[i]*rand_week_total[j,i]*rand_product_total[k,i]*rand_zipcode_total[l,i])
                    if a !=0:
                        forecast_year.append(years[i])
                        forecast_week.append(weeks[j])
                        forecast_product.append(product[k])
                        forecast_ZIP.append(zipcode[l])
                        forecast_qty.append(a)

def f2():
    demand_growth = np.array([10,15,20,23,26,30])
    rand_week_total = np.random.rand(52,6)
    rand_product_total = np.random.rand(23,6)
    rand_zipcode_total = np.random.rand(43,6)

    forecast_year = []
    forecast_week = []
    forecast_product = []
    forecast_ZIP = []
    forecast_qty = []

    years = np.array(range(2015, 2020))
    weeks = np.array(range(0, 52))
    product = np.array(range(0, 23))
    zipcode = np.array(range(0, 43))

    for i in range(len(years)):
        for j in range(len(weeks)):
            temp_ij = demand_growth[i]*rand_week_total[j,i]
            for k in range(len(product)):
                temp_ikj = temp_ij*rand_product_total[k,i]
                for l in range(len(zipcode)):
                    a = np.rint(temp_ikj*rand_zipcode_total[l,i])
                    if a !=0:
                        forecast_year.append(years[i])
                        forecast_week.append(weeks[j])
                        forecast_product.append(product[k])
                        forecast_ZIP.append(zipcode[l])
                        forecast_qty.append(a)

def f3():
    demand_growth = np.array([10,15,20,23,26,30])
    rand_week_total = np.random.rand(52,6)
    rand_product_total = np.random.rand(23,6)
    rand_zipcode_total = np.random.rand(43,6)

    forecast_year = []
    forecast_week = []
    forecast_product = []
    forecast_ZIP = []
    forecast_qty = []

    years = np.array(range(2015, 2020))
    weeks = np.array(range(0, 52))
    product = np.array(range(0, 23))
    zipcode = np.array(range(0, 43))

    for j in range(len(weeks)):
        temp_j = demand_growth*rand_week_total[j,:]
        for k in range(len(product)):
            temp_jk = temp_j * rand_product_total[k,:]
            for l in range(len(zipcode)):
                a = np.rint(temp_jk*rand_zipcode_total[l,:])
                for i in range(len(years)):
                    if a[i] !=0:
                        forecast_year.append(years[i])
                        forecast_week.append(weeks[j])
                        forecast_product.append(product[k])
                        forecast_ZIP.append(zipcode[l])
                        forecast_qty.append(a[i])


print(timeit.Timer(f1).timeit(5))
print(timeit.Timer(f2).timeit(5))
print(timeit.Timer(f3).timeit(5))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-25
    • 2022-01-26
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 2019-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多