我正在创建这个数组:
A=itertools.combinations(range(6),2)
我必须用numpy来操作这个数组,比如:
A.reshape(..
如果尺寸A为高,则命令list(A)
太慢。
更新1: 我已经尝试过hpaulj的解决方案,在这种特定的情况下有点慢,任何想法?
start=time.clock()
A=it.combinations(range(495),3)
A=np.array(list(A))
print A
stop=time.clock()
print stop-start
start=time.clock()
A=np.fromiter(it.chain(*it.combinations(range(495),3)),dtype=int).reshape (-1,3)
print A
stop=time.clock()
print stop-start
结果:
[[ 0 1 2]
[ 0 1 3]
[ 0 1 4]
...,
[491 492 494]
[491 493 494]
[492 493 494]]
10.323822
[[ 0 1 2]
[ 0 1 3]
[ 0 1 4]
...,
[491 492 494]
[491 493 494]
[492 493 494]]
12.289898
答案 0 :(得分:3)
我正在重新打开这个,因为我不喜欢链接的答案。接受的答案建议使用
np.array(list(A)) # producing a (15,2) array
但OP显然已经尝试list(A)
,并发现它很慢。
另一个答案建议使用np.fromiter
。但其评论中隐含的是fromiter
需要1d数组的注释。
In [102]: A=itertools.combinations(range(6),2)
In [103]: np.fromiter(A,dtype=int)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-103-29db40e69c08> in <module>()
----> 1 np.fromiter(A,dtype=int)
ValueError: setting an array element with a sequence.
所以在这个itertools中使用fromiter
需要以某种方式展平迭代器。
快速的时间安排表明list
不是缓慢的步骤。它将列表转换为一个缓慢的数组:
In [104]: timeit itertools.combinations(range(6),2)
1000000 loops, best of 3: 1.1 µs per loop
In [105]: timeit list(itertools.combinations(range(6),2))
100000 loops, best of 3: 3.1 µs per loop
In [106]: timeit np.array(list(itertools.combinations(range(6),2)))
100000 loops, best of 3: 14.7 µs per loop
我认为使用fromiter
的最快方法是使用惯用法combinations
来展平itertools.chain
:
In [112]: timeit
np.fromiter(itertools.chain(*itertools.combinations(range(6),2)),dtype=int)
.reshape(-1,2)
100000 loops, best of 3: 12.1 µs per loop
节省的时间不多,至少在这么小的尺寸上。 (fromiter
也需要count
,这会削弱另一个μs。对于较大的案例range(60)
,fromiter
占array
的一半时间。< / p>
快速搜索[numpy] itertools
会产生一些关于生成所有组合的纯粹numpy方式的建议。 itertools
很快,用于生成纯Python结构,但将它们转换为数组是一个很慢的步骤。
关于这个问题的挑剔点。
A
是一个生成器,而不是一个数组。 list(A)
确实生成了一个嵌套列表,可以将其松散地描述为数组。但它不是np.array
,也没有reshape
方法。
答案 1 :(得分:1)
获取N
元素的每个成对组合的另一种方法是使用(N, N)
生成np.triu_indices(N, k=1)
矩阵的上三角形的索引,例如:
np.vstack(np.triu_indices(6, k=1)).T
对于小型数组,itertools.combinations
将获胜,但对于大型 N ,triu_indices
技巧可以大大加快:
In [1]: %timeit np.fromiter(itertools.chain.from_iterable(itertools.combinations(range(6), 2)), np.int)
The slowest run took 10.46 times longer than the fastest. This could mean that an intermediate result is being cached
100000 loops, best of 3: 4.04 µs per loop
In [2]: %timeit np.array(np.triu_indices(6, 1)).T
The slowest run took 10.97 times longer than the fastest. This could mean that an intermediate result is being cached
10000 loops, best of 3: 22.3 µs per loop
In [3]: %timeit np.fromiter(itertools.chain.from_iterable(itertools.combinations(range(1000), 2)), np.int)
10 loops, best of 3: 69.7 ms per loop
In [4]: %timeit np.array(np.triu_indices(1000, 1)).T
100 loops, best of 3: 10.6 ms per loop