본문 바로가기
프로그램

[파이썬] 680배 빨라진다! 조건에 맞는 데이터 계산(병렬처리 하지 않고 Numba만 사용)

by 오디세이99 2025. 6. 3.
728x90
반응형

https://question99.tistory.com/1095

 

[파이썬] 조건에 맞는 데이터 계산(다중 for문)

어떤 데이터가 있을때 어떤 컬럼의 데이터들끼리 어떤 조건들로 찾거나 계산할때import timeimport pandas as pdimport numpy as npnp.random.seed(0) # 난수 생성 시 일관성을 위해 시드 설정### 1) 데이터 생성data_s

question99.tistory.com

 

https://question99.tistory.com/1096

 

[파이썬] 조건에 맞는 데이터 계산(Parallel, 병렬처리, 다중프로세스)

https://question99.tistory.com/1095 [파이썬] 조건에 맞는 데이터 계산(다중 for문)어떤 데이터가 있을때 어떤 컬럼의 데이터들끼리 어떤 조건들로 찾거나 계산할때import timeimport pandas as pdimport numpy as npnp.r

question99.tistory.com

 

https://question99.tistory.com/1096

 

[파이썬] 조건에 맞는 데이터 계산(Parallel, 병렬처리, 다중프로세스)

https://question99.tistory.com/1095 [파이썬] 조건에 맞는 데이터 계산(다중 for문)어떤 데이터가 있을때 어떤 컬럼의 데이터들끼리 어떤 조건들로 찾거나 계산할때import timeimport pandas as pdimport numpy as npnp.r

question99.tistory.com

 

Numba를 사용시 병렬처리(Parallel)는 사용하지 않아도 되지 않을까?

 

### 다중 for문
import time
import pandas as pd
import numpy as np

np.random.seed(0)  # 난수 생성 시 일관성을 위해 시드 설정

### 1) 데이터 생성
data_size = 2000
data = {
    'c1': np.random.randint(50, 201, size=data_size),  # 50에서 200 사이의 정수, 100개
    'c2': np.random.randint(50, 201, size=data_size),
    'c3': np.random.randint(50, 201, size=data_size),
    'c4': np.random.randint(50, 201, size=data_size),
    'c5': np.random.randint(50, 201, size=data_size),
    'c6': np.random.randint(50, 201, size=data_size),
    'c7': np.random.randint(50, 201, size=data_size),
    'c8': np.random.randint(50, 201, size=data_size),
    'c9': np.random.randint(50, 201, size=data_size),
    'c10': np.random.randint(50, 201, size=data_size)
}

# DataFrame 생성
df = pd.DataFrame(data)

@jit(nopython=True)
def run_simulation(lst_no, n_df):
    idx = 0
    max_idx = 0
    max_count = 0
    # max_case1 = 
    # max_case2 = 
    for item1 in lst_no:                             # 조건 1번째. 어떤 df의 컬럼을 사용할 것인지
        for item2 in lst_no:                         # 조건 2번째
            count1 = []
            count2 = []
            for i in range(len(n_df)):              # 데이터의 row별 조건 확인을 위한 반복문
                data1 = n_df[i][item1[0]]
                data2 = n_df[i][item1[1]]
                data3 = n_df[i][item2[0]]
                data4 = n_df[i][item2[1]]
                
                if data1 > data2:                 # 데이터의 조건 판단
                    count1.append(idx)
                elif data3 > data4:
                    count2.append(idx)
    
            count_sum = len(count1) + len(count2)     # 조건 결과
            if count_sum > max_count:                 # 조건 결과로 max 구하기
                max_idx = idx
                max_count = count_sum
                max_case1 = item1
                max_case2 = item2
            # print(f"[{idx}] {item1} : {item2} : {count_sum} : {max_idx} : {max_count}")
            # print(f"[{idx}] ({item1[0]},{item1[1]}) : ({item2[0]},{item2[1]}) : {count_sum} : {max_idx} : {max_count}")
            # combinations1.append([idx, item1, item2])
            idx += 1
    return max_idx, max_count, max_case1, max_case2


### 2) 조건의 조합(순열) 만들기
# col = ['c1','c2','c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'c10']
col = ['c1','c2','c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'c10']

lst = list(itertools.permutations(col, 2))     # 순열 만들기. [('c1', 'c2'), ('c1', 'c3'), ('c1', 'c4'), ('c1', 'c5'), ('c1', 'c6')...

lst_no = []
for i in range(len(lst)):
    n1 = col.index(lst[i][0])     # 해당 컬럼명(문자열)의 인덱스를 찾아 정수로 사용
    n2 = col.index(lst[i][1])
    lst_no.append((n1, n2))
# print(lst_no)

n_df = df[col].values

start_time = time.time()                       # 시작시간 저장

### 3) 데이터에서 조건으로 찾기
max_idx = 0
max_count = 0
max_case1 = []
max_case2 = []

max_idx, max_count, max_case1, max_case2 = run_simulation(lst_no, n_df)
# max_idx = run_simulation(lst_no, n_df)

### 4) 출력
print(f"Best case : {max_count:,} (idx={best_idx}), {max_case1}:{max_case2}")
print(f"Best case : {max_count:,} (idx={best_idx}), ({col[max_case1[0]]},{col[max_case1[1]]}):({col[max_case2[0]]},{col[max_case2[1]]})")

# 실행기간 계산 및 출력
end_time = time.time()
elapsed = end_time - start_time
minutes = int(elapsed // 60)
seconds = int(elapsed % 60)
print(f"\nRunning time: {minutes}m {seconds}sec")

 

병렬처리(Parallel)는 사용하지 않아도 빠름. 
더 빠른 것으로 보임.

 

다음과 같이 실행시간을 정밀하게 측정.

start_time_pc = time.perf_counter()
...
# CPU에서 최종 집계 시간도 별도로 측정 가능
start_cpu_post_processing = time.perf_counter()
# ... (CPU에서 최종 Best case 찾는 루프) ...
end_cpu_post_processing = time.perf_counter()
cpu_elapsed_time = end_cpu_post_processing - start_cpu_post_processing
print(f"CPU Post-processing time: {cpu_elapsed_time:.6f} seconds")

total_elapsed_time = end_cpu_post_processing - start_time_pc
print(f"Total end-to-end Running time: {total_elapsed_time:.6f} seconds")

다중 for문 일때 300 sec 에서 0.44sec로 680배 빨리 처리 할 수 있다.

 

https://question99.tistory.com/1100

 

[파이썬] 1,875배 빨라진다! 조건에 맞는 데이터 계산(Numba GPU 사용)

아래와 같이 실행속도를 더 빠르게 하는 방법을 진행해 보고 있습니다. https://question99.tistory.com/1095 [파이썬] 조건에 맞는 데이터 계산(다중 for문)어떤 데이터가 있을때 어떤 컬럼의 데이터들끼리

question99.tistory.com

 

728x90
반응형

댓글