Python 在某些条件下迭代集合最有效的方法是什么?
我有一个模拟装置,其中有一组元组。每个元组包含numpy数组中特定位置的索引 在某个时刻,我必须迭代这组元组,以应用3个条件过滤掉索引,然后我选择一个随机元组。我的代码如下:Python 在某些条件下迭代集合最有效的方法是什么?,python,optimization,set,conditional-statements,list-comprehension,Python,Optimization,Set,Conditional Statements,List Comprehension,我有一个模拟装置,其中有一组元组。每个元组包含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
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
在这里,我应用这三个条件遍历我的集合,然后从现有的剩余元组中选择一个随机元组。如您所见,这个条件依赖于coords,每次调用这个函数时,coords都是一个不同的元组
我的程序需要很长的时间来执行(我根据测试运行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)
订购人:累计时间
ncalls tottime percall cumtime percall文件名:lineno(函数)
1 0.038 0.038 10.004 10.004 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\SIMULATION\u Test.py:247(开始)
526 0.009 0.000 9.662 0.018 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\SIMULATION\u Test.py:232(重新定位)
526 0.003 0.000 9.652 0.018 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\SIMULATION\u Test.py:374(reloc\u findSpot)
526 9.643 0.018 9.643 0.018 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\SIMULATION\u Test.py:375()
500 0.013 0.000 5.330 0.011 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\SIMULATION\u Test.py:140(检索\u迭代)
500 0.012 0.000 4.627 0.009 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\SIMULATION\u Test.py:108(存储迭代)
1000 0.051 0.000 0.269 0.000 c:\Users\Eduardo\Desktop\Thesis Docs\SIMULATION\SIMULATION\u Test.py:363(rnd\u findSpot)
1000 0.187 0.000 0.204 0.000 C:\Users\Eduardo\AppData\Local\Programs\Python\Python38-32\lib\random.py:315(示例)
我的理解是列表理解基本上是执行for循环,所以我认为将其转换为for循环是无用的。
我的问题是,有没有一种方法可以更有效地遍历集合,并根据3个条件过滤出元组
如果需要,请提供一些额外信息:
- 我的仓库是一个带有1和0的3D numpy阵列
- 随着0和1的位置在整个模拟过程中的变化,元组集将随着这些值的变化而更新
- 列表理解中的第三个条件给了我足够接近的结果,但我对比较数据片段的理解不是很有信心
谢谢你的帮助 这是一个局部解决方案,可以适度提高速度 它仍然使用列表理解,但在更小的“元组”范围内循环。(迭代次数将少得多) 我在双引号中提到“tuple”,因为在这个解决方案中,
zero
不再是tuple
对象的集合。相反,zero
是一些大型N
的二维numpy
形状数组(N,3)
详细信息:
第1步,共3步:
将行zeros=set(map(tuple,np.argwhere(warehouse==0))
替换为以下内容:
zeros = np.argwhere(warehouse==0)
第2步,共3步:
在reloc\u findSpot()
中,在列表中引入此行之前:
filt_zeros = zeros[zeros[:,0] == coords[0]]
第3步,共3步:
在列表中:
将所有零
替换为过滤零
删除第一个条件
让我知道它与您的全尺寸数据集的配合情况。这是一个局部解决方案,可以适度提高速度
它仍然使用列表理解,但在更小的“元组”范围内循环。(迭代次数将少得多)
我在双引号中提到“tuple”,因为在这个解决方案中,zero
不再是tuple
对象的集合。相反,zero
是一些大型N
的二维numpy
形状数组(N,3)
详细信息:
第1步,共3步:
将行zeros=set(map(tuple,np.argwhere(warehouse==0))
替换为以下内容:
zeros = np.argwhere(warehouse==0)
第2步,共3步:
在reloc\u findSpot()
中,在列表中引入此行之前:
filt_zeros = zeros[zeros[:,0] == coords[0]]
第3步,共3步:
在列表中:
将所有零
替换为过滤零
删除第一个条件
让我知道它如何与您的全尺寸数据集配合。因此,最终我的解决方案是更改我的findSpot算法reloc_findSpot()
不再创建所有可能位置的列表,然后选择一个。现在,它返回与zeros
集中的条件匹配的第一个元素
这将我的运行时间从15秒减少到了0.4秒,可以运行1000个循环(需要测试更多循环的效率,但这已经是一个巨大的改进)。这是通过生产线实现的
relocSpot=next(如果ele[0]==coords[0]如果1不在仓库[:ele[0],ele[1],ele[2]]如果(仓库[-(ASdepth-1-ele[0]):,ele[1],ele[2]==warehouse[-(ASdepth-1-coords[0]),coords[1],coords[2]])。all()
我的结果似乎没有受到影响(我想因为集合没有排序,所以第一个匹配条件的项目总是随机的)。
谢谢大家的帮助 所以最后我的解决方案是改变我的findSpot算法reloc_findSpot()
不再创建所有可能位置的列表,然后选择一个。它现在返回冷杉