티스토리 뷰
728x90
반응형
이번 포스팅은 일반 알고리즘을 Pandas를 써서 빠르게 하는 내용입니다.
(LOC를 사용한 특정 Col의 Value 바꾸기)
오늘 일하는데, 아래와 같은 상황을 만났습니다.
해당 문제를 단순히 반복문으로 접근하면 아래와 같이 풀이가 가능합니다.
import pandas as pd
Data = pd.DataFrame({"a" : [5,9,7,8,1,2,6,3,7,8,4,9,2,1],
"b" : ["A","A","B","D","D","B","A","A","B","D","C","D","C","C"]})
Data["c"] = None
for i in Data.index:
if Data.at[i,"b"]=="C":
Data.at[i,"c"] = 1
하지만, 위 경우 Data의 길이가 짧으니 가능합니다.
하지만 Data의 Raw의 개수가 100만, 1000만, 1억개가 되면? 기다리다가 늙어죽을지도 모릅니다.
그러면 일반적인 Pandas의 LOC를 쓰면 가능할까요?
import pandas as pd
Data = pd.DataFrame({"a" : [5,9,7,8,1,2,6,3,7,8,4,9,2,1],
"b" : ["A","A","B","D","D","B","A","A","B","D","C","D","C","C"]})
Data["c"] = None
'''
for i in Data.index:
if Data.at[i,"b"]=="C":
Data.at[i,"c"] = 1
'''
#Data[Data.loc[:,"b"]=="C"]
#=>Data[Boolean List]를 활용해서 Data에서 col_b가 C인 Data만 subset
Data[Data.loc[:,"b"]=="C"].loc[:,"c"] = 1
=> "c"의 모든 값은 여전히 None
DataFrame[Boolean]형태로 때어온 Data에 대해서는 Value Change를 해도 원본 Table에 변화가 없어보입니다.
Pandas로 손쉽게 SIMD로 빠르게 처리할라 했더니, 마음처럼 되지가 않습니다.
이때 사용할 수 있는 방법이 DataFrame[Boolean, "col_nm"] = change_value입니다.
import pandas as pd
Data = pd.DataFrame({"a" : [5,9,7,8,1,2,6,3,7,8,4,9,2,1],
"b" : ["A","A","B","D","D","B","A","A","B","D","C","D","C","C"]})
Data["c"] = None
'''
for i in Data.index:
if Data.at[i,"b"]=="C":
Data.at[i,"c"] = 1
'''
#Data[Data.loc[:,"b"]=="C"].loc[:,"c"] = 1
#[Data.loc[:,"b"]=="C"][0]
#= Data의 b Col 기준으로 값이 C인 경우 True
#그 외에는 False값 반환
Data.loc[[Data.loc[:,"b"]=="C"][0],"c"] = 1
print(Data)
a b c
0 5 A None
1 9 A None
2 7 B None
3 8 D None
4 1 D None
5 2 B None
6 6 A None
7 3 A None
8 7 B None
9 8 D None
10 4 C 1
11 9 D None
12 2 C 1
13 1 C 1
이렇게하면 SIMD를 사용하여 for 반복문은 쓰는것 보다 매우 빠른 결과물을 얻을 수 있습니다.
마지막으로 for 반복문과 Pandas 를 활용한 방법의 실행시간을 비교한 결과입니다.(random한 100만개의 raw 생성)
import pandas as pd
import random
import time
Data = pd.DataFrame({"a" : [random.randint(1,100) for i in range(1000000)],
"b" : [["A","B","C","D"][random.randint(0,3)] for i in range(1000000)]})
Data["c"] = None
start = time.time()
for i in Data.index:
if Data.at[i,"b"]=="C":
Data.at[i,"c"] = 1
print("time :", time.time() - start)
==>time : 12.38511323928833
start = time.time()
Data.loc[[Data.loc[:,"b"]=="C"][0],"c"] = 1
print("time :", time.time() - start)
==>time : 0.06506919860839844
for 반복문은 12.4초, Pandas를 사용한 경우 0.065초로, 약 190배의 속도가 차이나는것을 볼 수 있습니다.
728x90
반응형
'Python 잡지식' 카테고리의 다른 글
Python의 매개변수 전달방식 (0) | 2021.03.13 |
---|---|
Event Listener의 정체 (0) | 2021.03.10 |
Python의 Thread1 (0) | 2021.03.09 |
여러개의 List를 기준으로 정렬하기 (0) | 2021.02.23 |
특정 List를 기준으로 Data를 정렬하기 (0) | 2021.02.21 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 완전탐색 알고리즘
- heap
- Greedy알고리즘
- 코딩테스트
- prime number
- hash
- Search알고리즘
- 자료구조
- 모바일청첩장
- react
- C++
- 알고리즘
- Python
- stack
- SIMD
- 동적계획법
- 셀프모청
- 사칙연산
- 청첩장
- 분할정복
- 이분탐색
- javascript
- GDC
- 프로그래머스
- 병렬처리
- AVX
- 컴퓨터그래픽스
- git
- Sort알고리즘
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
글 보관함