python - 在某些条件下迭代集合的最有效方法是什么?
问题描述
我有一个模拟设置,其中有一组元组。每个元组都包含我的 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[1],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 和 1 的位置而更新。
- 我的列表理解中的第三个条件给了我足够接近的结果,但我对比较数据切片的理解不是很有信心。
谢谢您的帮助!
解决方案
这是一个部分解决方案,它将适度提高速度。
它仍然使用列表推导,但循环的“元组”范围要小得多。(迭代次数会少得多)
我在双引号中提到“元组”,因为在这个解决方案中,zeros
不再是set
对象tuple
。相反,是一些大型zeros
的二维numpy
形状数组。(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 步):
在列表理解中:
- 全部替换
zeros
为filt_zeros
- 删除第一个条件
让我知道它与您的全尺寸数据集的关系。
推荐阅读
- git - 如何删除(壁球)未命名的 git 分支
- php - 如果 ";" 是否有任何额外的解释器负载 设置到下一行?
- gmail - 从 AWS SES 发送 AMP 电子邮件时,GMAIL 上未显示
- php - 从复选框传递值并将它们显示在 Laravel 的另一个页面中的问题
- swift - 如何使用 indexpathforselectedrow 从我的结构数组中获取实例?
- windows - Windows批处理:在调用批处理打开的cmd窗口中运行命令?
- java - Spring 3:具有方面的异步方法中的“范围'请求'对于当前线程不活动”
- ios - 如何在没有应用程序预览的情况下将 pkpass 文件添加到钱包?
- arduino - Vorto Arduino Generator:没有已知的数据类型参数的转换百分比
- cluster-computing - 如何在 slurm 中获取节点上分配的作业列表?