itertools产品加速 [英] itertools product speed up
问题描述
我使用itertools.product生成长度为13的4个元素的所有可能变体.4和13可以是任意的,但实际上,我得到4 ^ 13的结果,这是很多的.我需要将结果作为一个Numpy数组,当前需要执行以下操作:
c = it.product([1,-1,np.complex(0,1), np.complex(0,-1)], repeat=length)
sendbuf = np.array(list(c))
在其中插入一些简单的性能分析代码后,第一行看起来几乎是瞬时的,而转换为列表然后转换为Numpy数组大约需要3个小时. 有没有办法使它更快?我可能忽略的确很明显.
谢谢!
itertools.product()
的NumPy等效值为numpy.indices()
,但它只会为您提供范围为0,...,k-的范围的乘积1:
numpy.rollaxis(numpy.indices((2, 3, 3)), 0, 4)
array([[[[0, 0, 0],
[0, 0, 1],
[0, 0, 2]],
[[0, 1, 0],
[0, 1, 1],
[0, 1, 2]],
[[0, 2, 0],
[0, 2, 1],
[0, 2, 2]]],
[[[1, 0, 0],
[1, 0, 1],
[1, 0, 2]],
[[1, 1, 0],
[1, 1, 1],
[1, 1, 2]],
[[1, 2, 0],
[1, 2, 1],
[1, 2, 2]]]])
对于特殊情况,您可以使用
a = numpy.indices((4,)*13)
b = 1j ** numpy.rollaxis(a, 0, 14)
(由于数组太大,因此无法在32位系统上运行.从我可以测试的大小推断出来,它应该在不到一分钟的时间内运行.)
EIDT:只需提一下:numpy.rollaxis()
的调用或多或少是装饰性的,以获得与itertools.product()
相同的输出.如果您不关心索引的顺序,则可以忽略它(但是只要您没有任何将数组转换为连续数组的后续操作,它还是很便宜的.)>
要获得确切的类似物
numpy.array(list(itertools.product(some_list, repeat=some_length)))
您可以使用
numpy.array(some_list)[numpy.rollaxis(
numpy.indices((len(some_list),) * some_length), 0, some_length + 1)
.reshape(-1, some_length)]
这完全无法理解-告诉我是否应该进一步解释它了:)
I use itertools.product to generate all possible variations of 4 elements of length 13. The 4 and 13 can be arbitrary, but as it is, I get 4^13 results, which is a lot. I need the result as a Numpy array and currently do the following:
c = it.product([1,-1,np.complex(0,1), np.complex(0,-1)], repeat=length)
sendbuf = np.array(list(c))
With some simple profiling code shoved in between, it looks like the first line is pretty much instantaneous, whereas the conversion to a list and then Numpy array takes about 3 hours. Is there a way to make this quicker? It's probably something really obvious that I am overlooking.
Thanks!
The NumPy equivalent of itertools.product()
is numpy.indices()
, but it will only get you the product of ranges of the form 0,...,k-1:
numpy.rollaxis(numpy.indices((2, 3, 3)), 0, 4)
array([[[[0, 0, 0],
[0, 0, 1],
[0, 0, 2]],
[[0, 1, 0],
[0, 1, 1],
[0, 1, 2]],
[[0, 2, 0],
[0, 2, 1],
[0, 2, 2]]],
[[[1, 0, 0],
[1, 0, 1],
[1, 0, 2]],
[[1, 1, 0],
[1, 1, 1],
[1, 1, 2]],
[[1, 2, 0],
[1, 2, 1],
[1, 2, 2]]]])
For your special case, you can use
a = numpy.indices((4,)*13)
b = 1j ** numpy.rollaxis(a, 0, 14)
(This won't run on a 32 bit system, because the array is to large. Extrapolating from the size I can test, it should run in less than a minute though.)
EIDT: Just to mention it: the call to numpy.rollaxis()
is more or less cosmetical, to get the same output as itertools.product()
. If you don't care about the order of the indices, you can just omit it (but it is cheap anyway as long as you don't have any follow-up operations that would transform your array into a contiguous array.)
EDIT2: To get the exact analogue of
numpy.array(list(itertools.product(some_list, repeat=some_length)))
you can use
numpy.array(some_list)[numpy.rollaxis(
numpy.indices((len(some_list),) * some_length), 0, some_length + 1)
.reshape(-1, some_length)]
This got completely unreadable -- just tell me whether I should explain it any further :)
这篇关于itertools产品加速的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!