微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在某些条件下迭代集合的最有效方法是什么?

如何解决在某些条件下迭代集合的最有效方法是什么?

我有一个模拟设置,其中有一组元组。每个元组都包含我的numpy数组中特定位置的索引。

在某个时候,我必须遍历这组元组以应用3个条件来筛选出索引,然后选择一个随机元组。我的代码如下:

def fillASRS(arr,fillLevel):
    toFill = round(float(vol*(fillLevel/100)))
    shape = arr.shape
    arr_1D = arr.reshape(-1)
    inds = np.random.choice(arr_1D.size,toFill,replace = False)
    arr_1D[inds] = 1
    arr_3D = np.array(arr_1D.reshape(shape))
    arr_3D.astype(np.int8)
    return arr_3D

warehouse = np.zeros([ASdepth,ASheight,ASlength])
warehouse = warehouse.astype(np.int8)
fillASRS(warehouse,z)
zeros = set(map(tuple,np.argwhere(warehouse==0)))

这是从开始执行的,创建了我的3D numpy数组,并用1和0填充,并且创建了我的数组为0的位置集。

然后我的代码如下:

def reloc_findSpot(coords):
    new_arr=[ele for ele in zeros if ele[0]==coords[0] if 1 not in warehouse[:ele[0],ele[1],ele[2]] if (warehouse[-(ASdepth-1-ele[0]):,ele[2]] == warehouse[-(ASdepth-1-coords[0]):,coords[1],coords[2]]).all]
    random_idx=np.random.randint(len(new_arr))
    relocSpot = new_arr[random_idx]
    return relocSpot

在这里,我使用这三个条件遍历集合,然后从现有剩余条件中选择一个随机元组。如您所见,这种情况取决于坐标,每次调用函数时,坐标就不同。

我的程序需要很长时间才能执行(我根据测试运行1000-100000次迭代),当我对其进行概要分析时,它告诉我,我的大部分执行时间都花在了列表理解上,如下所示:

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.038    0.038   10.004   10.004 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\Simulation_Test.py:247(start)
      526    0.009    0.000    9.662    0.018 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\Simulation_Test.py:232(relocation)
      526    0.003    0.000    9.652    0.018 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\Simulation_Test.py:374(reloc_findSpot)
      526    9.643    0.018    9.643    0.018 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\Simulation_Test.py:375(<listcomp>)
      500    0.013    0.000    5.330    0.011 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\Simulation_Test.py:140(retrieval_Iteration)
      500    0.012    0.000    4.627    0.009 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\Simulation_Test.py:108(storage_Iteration)
     1000    0.051    0.000    0.269    0.000 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\Simulation_Test.py:363(rnd_findSpot)
     1000    0.187    0.000    0.204    0.000 C:\Users\Eduardo\AppData\Local\Programs\Python\python38-32\lib\random.py:315(sample)

我的理解是列表理解基本上是在执行for循环,因此我认为将其转换为for循环是没有用的。 我的问题是,有没有一种方法可以更有效地遍历集合,并根据3种条件过滤出元组

如果需要,一些额外的信息:

  • 我的仓库是一个1和0的3D numpy数组
  • 随着整个模拟过程中这些值的变化,元组的集合将更新为0和1s的位置。
  • 列表理解中的第三个条件使我获得了足够接近的结果,但是我对比较数据片段的理解并不十分自信。

谢谢您的帮助!

解决方法

这是部分解决方案,可以使速度适度提高。

它仍然使用列表推导,但是在较小的“元组”范围内循环。 (迭代次数将大大减少)

我在双引号中提到“元组”,因为在此解决方案中,zeros不再是set对象的tuple。相反,zerosnumpy的二维(N,3)形状的二维N数组。

详细信息:

第1步,共3步:

用以下内容替换行zeros = set(map(tuple,np.argwhere(warehouse==0)))

zeros = np.argwhere(warehouse==0)

第2步,共3步:

reloc_findSpot()中,在列表理解之前引入以下行:

filt_zeros = zeros[zeros[:,0] == coords[0]]

第3步,共3步:

在列表理解中:

  1. 将所有zeros替换为filt_zeros
  2. 删除第一个条件

让我知道它与全面数据集的关系。

,

最后,我的解决方案是更改find​​Spot算法。 reloc_findSpot()不再创建所有可能位置的列表,然后选择一个。现在,它返回第一个符合我在zeros集中的条件的元素。

对于1000次循环运行,这将我的运行时间从15秒减少到0.4秒(必须测试更多循环的效率,但这已经是一个很大的改进)。这是通过生产线实现的 relocSpot = next(ele for ele in zeros if ele[0]==coords[0] if 1 not in warehouse[:ele[0],ele[1],ele[2]] if (warehouse[-(ASdepth-1-ele[0]):,ele[2]] == warehouse[-(ASdepth-1-coords[0]):,coords[1],coords[2]]).all())

看来我的结果没有受到影响(我猜因为集合没有排序,所以匹配条件的第一个项目总是随机的)。 谢谢大家的帮助!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。