2016-10-15 4 views
-1

길이 (8) 인 문자열의 대체 (즉, 데카르트 제품)로 모든 조합을 얻으려고합니다. 출력이 너무 커서 한 번에 메모리에 저장하는 데 문제가 있으므로 프로세스가 완료되기 전에 프로세스가 종료됩니다.파이썬에서 생성자를 통한 문자 조합

import numpy as np 

def cartesian(arrays, out=None): 
"""Generate a cartesian product of input arrays. 
Parameters 
---------- 
arrays : list of array-like 
    1-D arrays to form the cartesian product of. 
out : ndarray 
    Array to place the cartesian product in. 
Returns 
------- 
out : ndarray 
    2-D array of shape (M, len(arrays)) containing cartesian products 
    formed of input arrays. 
Examples 
-------- 
>>> cartesian(([1, 2, 3], [4, 5], [6, 7])) 
array([[1, 4, 6], 
     [1, 4, 7], 
     [1, 5, 6], 
     [1, 5, 7], 
     [2, 4, 6], 
     [2, 4, 7], 
     [2, 5, 6], 
     [2, 5, 7], 
     [3, 4, 6], 
     [3, 4, 7], 
     [3, 5, 6], 
     [3, 5, 7]]) 
""" 
arrays = [np.asarray(x) for x in arrays] 
shape = (len(x) for x in arrays) 
dtype = arrays[0].dtype 

ix = np.indices(shape) 
ix = ix.reshape(len(arrays), -1).T 

if out is None: 
    out = np.empty_like(ix, dtype=dtype) 

for n, arr in enumerate(arrays): 
    out[:, n] = arrays[n][ix[:, n]] 

return out 

가 어떻게 대신 한 번에 메모리에 모든 것을 저장하는 결과에서 발전기를 반환 할 것 :

파이썬의 다음 stdlib itertools보다 훨씬 더 빠른 내가 사용하는 코드입니다?

+0

당신이 필요 생성기 함수를 생성하기 위해'yield' 문을 사용하십시오. – Nf4r

답변

1

다른 질문에서 내 인상 product가 반복적으로 발생 직교 조합의 가장 빠른 방법이다 :

In [494]: g=itertools.product([1,2,3],[4,5],[6,7]) 
In [495]: list(g) 
Out[495]: 
[(1, 4, 6), 
(1, 4, 7), 
(1, 5, 6), 
(1, 5, 7), 
(2, 4, 6), 
(2, 4, 7), 
(2, 5, 6), 
(2, 5, 7), 
(3, 4, 6), 
(3, 4, 7), 
(3, 5, 6), 
(3, 5, 7)] 

귀하의 코드는 np.indices의 매핑입니다 느리게 :

In [499]: timeit np.indices((3,2,2)).reshape(3,-1).T 
The slowest run took 11.08 times longer than the fastest. This could mean that an intermediate result is being cached. 
10000 loops, best of 3: 61.6 µs per loop 
In [500]: timeit list(itertools.product([1,2,3],[4,5],[6,7])) 
100000 loops, best of 3: 3.51 µs per loop