2016-09-22 4 views
1

나는 항목의 목록이 아래 rows에 표시되는 빈도를 계산하는 기능이 있습니다, 현실에서함수 내에서 병렬 처리가 가능합니까?

def count(pair_list): 
    return float(sum([1 for row in rows if all(item in row.split() for item in pair_list)])) 

if __name__ == "__main__": 
    pairs = [['apple', 'banana'], ['cookie', 'popsicle'], ['candy', 'cookie'], ...] 
    # grocery transaction data 
    rows = ['apple cookie banana popsicle wafer', 'almond milk eggs butter bread', 'bread almonds apple', 'cookie candy popsicle pop', ...] 

    res = [count(pair) for pair in pairs] 

len(rows)10000하고 18000 요소 pairs에있다, 그래서 count()의 지능형리스트의 컴퓨팅 비용 주요 기능에있는 것이 비쌉니다. 어느 쪽이 빨리 실행되지 않습니다

from multiprocessing.dummy import Pool as ThreadPool 
import multiprocessing as mp 

threadpool = ThreadPool(processes = mp.cpu_count()) 

res = threadpool.map(count, pairs) 

:

는 좀 병렬 처리를 시도했다. 실제로, 15 분 후에, 나는 끝내고 있기 위하여 보지 않기 때문에 다만 일을 그만 뒀다. 두 가지 질문 : 1) count()에서 이루어지는 실제 검색 속도를 높이려면 어떻게해야합니까? 2) threadpool.map 프로세스의 상태를 확인하려면 어떻게해야합니까? 즉, 반복 할 페어의 수는 몇 개인 지 확인하십시오.

+1

큰 '행'을 공유하는 중입니다. chunkksize = 100을'map'에 전달하십시오. – khachik

+1

및 진행에 대한 질문 - imap을 사용하십시오. – khachik

+0

나는 진짜 문제가'count()'에있는 목록 이해력이어야한다고 생각한다. 그게 병목 현상이 아닐까요, 여기,'쌍 (pair)'의 모든 p를 반복하여'count (p)'를 얻는 것일까 요? – blacksite

답변

1

1) 계산의 전체 복잡성은 엄청난이며, 다른 소스에서 온다 :

가) 당신은 계산의 낮은 수준에 행을 분할, 그래서 파이썬은 모든 반복에 대한 새 행 분할을 만들 수 있습니다. 이를 방지하기 위해 행을 미리 계산할 수 있습니다. 이런 식으로 뭔가를 ("계산"기능에 약간의 변화) 일을 할 것입니다 :

rows2 = [row.split() for row in rows] 

B)를 당신은 당신은 단지 다른 목록에 단어의 존재를 확인해야에도 불구하고, 목록 항목 하나 하나를 비교합니다. 여기에서 우리는 더 조정할 수 있습니다 (그리고 "계산"기능에 rows2 대신 rows3 사용) : 당신은 행에있는 모든 단어 쌍의 모든 단어를 확인

rows3 = [set(row.split()) for row in rows] 

def count(pair_list): 
    return float(sum([1 for row in rows3 if all(item in row for item in pair_list)])) 

C). 계산은 원래 버전의 "카운트"기능 호출 당 2 * len (행) * len (행) 반복을 필요로하는 반면 적은 수입니다. 옵션 b)의 경우에는 2 * len (행)까지 가능하지만 2 개가 아닌 한 쌍마다 한 세트 룩업 할 수 있습니다. 트릭은 모든 행에 대해 가능한 모든 단어 * 단어 조합을 준비하는 것입니다 이 집합에 해당 튜플이 있는지 확인하십시오. 그래서, 주요 기능으로 복잡한 불변의 검색 구조를 만들 : 그래서

def count2(pair): 
    return float(len([1 for row in rows4 if(pair in row)])) 

당신이 조금 다른 호출 :

지금
rows4 = [set((a, b) for a in row for b in row) for row in rows2] 

과 다를 것 "계산"을 대신 목록의 튜플합니다 : res = [pair 쌍의 쌍에 대한 count2 (튜플 (쌍))

검색 구조 생성은 시간과 공간에서 행 당 len (row.split())^2를 사용하므로 행이 길면, 최적이 아닙니다. 결국 옵션 b)가 더 좋을 수 있습니다.

2) "개수"에 대한 호출 수를 예측할 수 있습니다. 이는 "len (쌍)"입니다. "count"함수의 호출 횟수를 계산하고 1000 회 호출 할 때마다 디버그 인쇄를합니다.

+0

도움이됩니다. 전체 스크립트가 이제 날아갑니다! – blacksite

관련 문제