将 itertools 数组转换为 numpy 数组

ste*_*_B. 7 python numpy python-itertools

我正在创建这个数组:

A=itertools.combinations(range(6),2)
Run Code Online (Sandbox Code Playgroud)

我必须用 numpy 操作这个数组,比如:

A.reshape(..
Run Code Online (Sandbox Code Playgroud)

如果维度是 A 高,则命令list(A)太慢。

如何将 itertools 数组“转换”为 numpy 数组?

更新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
Run Code Online (Sandbox Code Playgroud)

结果:

[[  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
Run Code Online (Sandbox Code Playgroud)

hpa*_*ulj 5

我重新打开这个是因为我不喜欢链接的答案。接受的答案建议使用

np.array(list(A))  # producing a (15,2) array
Run Code Online (Sandbox Code Playgroud)

但是 OP 显然已经尝试过list(A),并且发现它很慢。

另一个答案建议使用np.fromiter. 但埋在其注释中的是fromiter需要一维数组的注释。

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.
Run Code Online (Sandbox Code Playgroud)

所以使用fromiter这个 itertools 需要以某种方式扁平化迭代器。

一组快速的时间安排表明这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
Run Code Online (Sandbox Code Playgroud)

我认为最快的使用方法fromitercombinations用惯用的方式将其展平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
Run Code Online (Sandbox Code Playgroud)

节省的时间不多,至少在这个小尺寸上。(fromiter还需要 a count,这又减少了一个 µs。对于较大的情况,range(60)fromiter花费的时间是 的一半array


快速搜索[numpy] itertools会发现一些关于生成所有组合的纯 numpy 方法的建议。 itertools速度很快,用于生成纯 Python 结构,但将它们转换为数组是一个缓慢的步骤。


关于这个问题的一个挑剔点。

A是一个生成器,而不是一个数组。 list(A)确实会产生一个嵌套列表,它可以被松散地描述为一个数组。但它不是np.array,也没有reshape方法。