1

을 파이썬에서 multiprocessing 모듈을 사용하여 병렬 처리하려고했다. 나는 다른 프로세스의 나머지 다른 열과 함께 한 프로세스와 두 번째 열의 모든 열을 나머지와 함께 하나의 열과 계산 상관 값을 취하려고합니다. 모든 프로세스에서 결과 행을 쌓아서 상관 관계 행렬의 위쪽을 채우는 방식으로이 방법을 계속 사용하고 있습니다.파이썬 병렬 상관 관계가 단일 프로세스 상관 관계보다 느리다

나는 모양이 (678461, 210) 인 표본 데이터를 가져 와서 평행 방법을 시도했으며 df.corr()이고 실행 시간이 각각 214.40s42.64s입니다. 그래서, 필자의 병렬화 된 방법은 더 많은 시간이 걸립니다.

개선 할만한 방법이 있습니까? _correlation에서

import multiprocessing as mp 
import pandas as pd 
import numpy as np 
from time import * 

def _correlation(args): 

    i, mat, mask = args 
    ac = mat[i] 

    arr = [] 

    for j in range(len(mat)): 
     if i > j: 
      continue 

     bc = mat[j] 
     valid = mask[i] & mask[j] 
     if valid.sum() < 1: 
      c = NA  
     elif i == j: 
      c = 1. 
     elif not valid.all(): 
      c = np.corrcoef(ac[valid], bc[valid])[0, 1] 
     else: 
      c = np.corrcoef(ac, bc)[0, 1] 

     arr.append((j, c)) 

    return arr 

def correlation_multi(df): 

    numeric_df = df._get_numeric_data() 
    cols = numeric_df.columns 
    mat = numeric_df.values 

    mat = pd.core.common._ensure_float64(mat).T 
    K = len(cols) 
    correl = np.empty((K, K), dtype=float) 
    mask = np.isfinite(mat) 

    pool = mp.Pool(processes=4) 

    ret_list = pool.map(_correlation, [(i, mat, mask) for i in range(len(mat))]) 

    for i, arr in enumerate(ret_list): 
     for l in arr: 
      j = l[0] 
      c = l[1] 

      correl[i, j] = c 
      correl[j, i] = c 

    return pd.DataFrame(correl, index = cols, columns = cols) 

if __name__ == '__main__': 
    noise = pd.DataFrame(np.random.randint(0,100,size=(100000, 50))) 
    noise2 = pd.DataFrame(np.random.randint(100,200,size=(100000, 50))) 
    df = pd.concat([noise, noise2], axis=1) 

    #Single process correlation  
    start = time() 
    s = df.corr() 
    print('Time taken: ',time()-start) 

    #Multi process correlation 
    start = time() 
    s1 = correlation_multi(df) 
    print('Time taken: ',time()-start) 

답변

0

결과는 Pool 간 통하여 통신을 실행하는 방법에 작업자 프로세스로 이동한다.

이것은 반환 데이터가 절인되고, 다른 프로세스로 보내지고, unpickleing되어 결과 목록에 추가된다는 것을 의미합니다. 이것은 시간이 걸리고 본래 순차적 인 과정입니다.

map은 IIRC가 보낸 순서대로 반품을 처리합니다. 따라서 한 번의 반복 작업이 비교적 오래 걸리면 다른 결과가 기다릴 수 있습니다. 도착한 즉시 결과를 산출하는 imap_unordered을 사용해 볼 수 있습니다.