python - map 에서 항상 들어가는 하나와 변형되는 것의 조합을 넣는 법

조회수 466회
from multiprocessing import Pool
dist_result = []

with Pool() as p:
    dist_result.append(p.map(dist_cal, !!!!(total_point, range(100) !!!!))

느낌표로 쌓인 부분이 모르겠는 부분입니다. 구현하고자 하는 코드의 원하는 바는 다음과 같습니다.

기본적으로 total_point 는 100 차원 인티저의 수백만개 집합입니다. 예) [ [1,2,3,...100] , [-1,2,3...], [12,4,2,...] ...]

dist_cal 은 함수입니다. 내부 점들간의 유클리드 거리를 구합니다. 단, 차원을 넣어주면 점들 중에서 그 넣어준 차원까지만 반영합니다

import itertools
def dist_cal(points_list, dim):

    result = 0
    for combi in itertools.combinations(points_list, 2):
        tmp = 0
        for i in range(dim):
            tmp += (combi[0][i]-combi[1][i])**2
        result += tmp**0.5

    return result

0차원에서 100차원까지 차원을 늘려가면서 점들간의 거리의 변화를 관측하려 하는데, 연산량이 많아서 병렬화 시키는 것이 목표인 코드입니다.

다시 질문하고자 하는 코드로 돌아가면

from multiprocessing import Pool
dist_result = []

with Pool() as p:
    dist_result.append(p.map(dist_cal, !!!!(total_point, range(100) !!!!))

total_point 는 모든 병렬 연산에서 바뀌지 않는 기본 인풋입니다. 그러나 이것이 단지 0~100을 다르게 실행하고자 하는데, 이것을 병렬실행 하기 위해서 p.map() 에 넣을 때, 함수 하나, 그리고 그 함수의 인자들을 따로 넣어 주는데

이 인자들을 생성할 때,

(고정된 토탈포인트, 계속 바뀌는 1~100의 숫자) 의 형태로 생성하는 방법을 몰라서 이럽니다.

부탁드립니다.

==============================

def genero(po, N):
    count = 0
    for i in range(N):
        yield po, i

with Pool() as p:
    dist_result.append(p.map(dist_cal, genero(total_point, 10) ))

로 접근해 보고 있는데, 맞는 접근방법인지 모르겠습니다,. 왜 안될까요;;;;

1 답변

  • 간략하게 풀어서 적으면...

    0~99개의 숫자를 섞어 달라는 의미죠?

    import random
    
    L = list(range(100)) # 0~99 가 저장되어 있음
    random.shuffle(L) # L의 요소들을 섞어줌
    
    print(L)
    [56, 43, 52, 7, 92, 97, 42, 79, 66, 80, 55, 69, 41, 91, 34, 2, 23, 49, 10, 6, 64, 30, 98, 87, 17, 51, 47, 85, 45, 72, 5, 81, 3, 93, 16, 67, 99, 25, 28, 86, 95, 78, 22, 14, 0, 36, 1, 15, 27, 89, 32, 48, 62, 40, 37, 74, 31, 90, 76, 84, 68, 24, 57, 60, 18, 12, 38, 88, 44, 26, 70, 29, 65, 50, 73, 71, 53, 63, 4, 33, 94, 13, 75, 82, 96, 20, 19, 39, 61, 9, 46, 58, 8, 11, 59, 77, 83, 54, 35, 21]
    

    그런데 코드를 보니 조금 틀렸습니다. 인수가 2개 이상이므로 starmap 을 사용해야 합니다.(버전 3.3 이상)

    total_point 는 같은 값으로 100번 되어야 할 것이구요. sample 은 shuffle 과 같이 요소들을 섞지만 새로운 list를 반환합니다.

    with Pool() as p:
        dist_result.append(p.starmap(dist_cal, zip([total_point] * 100, random.sample(range(100), 100)))
    
    • starmap 부분은 공부를 좀 더 해보겠습니다. 근데 total_point 가 꽤 큽니다. total_point*100 부분을 회피하고 total_point 단독으로 쓰는 법을 찾는 질문에 가깝습니다. Laser-Cho 2019.7.28 14:39
    • zip 결과는 제너네이터입니다. lazy 연산을 하기 때문에 total_point*100 를 모두 메모리에 올리는 구조가 아닙니다. 정영훈 2019.7.29 11:46

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)