데이터 사이언스를 시작할 때 주로 사용하는 언어는 R과 Python이 있습니다.
보통 개발을 시작하신 분들은 python으로 주로 입문하게 되죠. 이 때 주로 사용하는 라이브러리는 Pandas 라는 라이브러리입니다.
pandas 는 여러 파일을 파싱하는 것부터 전체 데이터 테이블을 NumPy 형태의 행렬 배열로 변환하는 다양하게 이용가능 합니다. 이런 기능들이 pandas가 데이터 사이언스와 머신러닝에서 잘 사용되는 이유입니다.
이런 pandas에게도 단점이 있으니 데이터가 많아질 수록 사용하는 메모리가 늘어나고 속도가 느려진다는 것입니다.
물론 pandas에서 천만 row도 처리 가능할 수 있지만, 그 경우에 10기가의 메모리가 필요합니다. 또한 pandas는 싱글코어로만 작동하고 ram의 범위 안에서만 작동합니다.
이런 단점들을 해소하기 위해 다양한 라이브러리들이 있습니다.
그 중에 modin, dask, vaex 가 있습니다.
간략히 살펴보면 다음과 같습니다.
1. dask
1) 기본적으로 pandas보다는 느리지만 큰 데이터에도 잘 작동한다.
2) 여러개의 머신이나 하나의 머신에서 여러개의 코어를 작동하기에 좋다.
3) 메모리를 초과하는 데이터도 다룰 수 있다.
2. modin
1) pandas의 함수와 fallback을 재구현한 DataFrame을 위한 새로운 'algebra' 입니다. (단순히 Pandas 만을 위한 게 아님)
2) 어떤 코드 수정도 없이 행과 열을 자동으로 병렬로 사용한다.
3) 내부적으로 Ray 나 dask 를 사용합니다.
-> dask 등이 pandas를 대체하기 위한 framework 라면 modin은 그런 dask를 pandas 문법처럼 사용하게 해주는 api 와 유사합니다.
3. vaex
1) pandas와 상관없는 pandas와 유사한 새로운 프로젝트
2) 램에 효율적인 새로운 string 타입을 갖고 있어 string 타입을 다룰 때 좋다.
3) 메모리 매핑 lazy computation
4) 수억개의 데이터를 랩탑에서 사용 가능
4.요약 결론
1) modin은 in-ram dataset 에서 코드 수정없이 더 빠른 속도를 원할 때 사용
2) dask는 메모리보다 더 큰 데이터셋을 사용할 때 사용
3) vaex는 memory mapped (HDF5) datasets이나 string 처리가 많을 때 사용
으로 요약할 수 있겠습니다.
간단한 실습을 통해 좀 더 비교를 해봅시다.
우선 라이브러리를 설치합니다.
pip install vaex |
* modin[dask] 의 경우 아직 정식은 아니지만 사용하였습니다.
jupyter notebook에선 앞에 !를 붙이고 실행시키면 되겠습니다.
import pandas as pd |
실제 문법 및 성능을 비교해보겠습니다.
시간 측정은 %time을 사용하였습니다.
* 제 환경은 노트북 환경으로 GPU가 없습니다.
* 데이터의 크기는 약 2GB를 조금 넘습니다.
%time pandas_df = pd.read_csv('data.csv') %time dask_df = dd.read_csv('data.csv') %time modin_df = mp.read_csv('data.csv') %time vaex_df = vaex.from_csv('data.csv') |
pandas: CPU times: user 15.4 s, sys: 2.34 s, total: 17.8 s Wall time: 17.7 s
dask: CPU times: user 10.2 ms, sys: 3.39 ms, total: 13.6 ms Wall time: 10.2 ms
modin: CPU times: user 2.64 s, sys: 1.43 s, total: 4.07 s Wall time: 11 s
vaex: CPU times: user 27.8 s, sys: 3.02 s, total: 30.8 s Wall time: 31.8 s
일단 dask의 비교 불가한 속도네요.. modin은 의미있는 속도를 냈습니다. vaex는 많이 느렸습니다.
그리고 눈여겨볼 점은 vaex의 경우 문법이 많이 다르다는 걸 알 수 있습니다.
속도: dask > modin > pandas > vaex
재밌는 점은 dask의 비교불가능한 속도는 lazy compute의 영향으로 실제로 계산을 하지 않았다는 점입니다.
*lazy compute란 실제로 값이 사용될 때까진 연산을 하지 않고 미루다 정말로 값이 필요할 때 계산을 하여 불필요한 연산 시간을 줄이는 것입니다.
그래서 단순히 dask_df 를 출력하면 데이터의 값을 보여주지 않고 dask_df.head()를 하면 값이 보입니다.
시간의 차이도 다른 라이브러리들은 head 출력 시 최대 6ms인 것에 비교하면 41.7ms 로 많이 차이가 납니다. (wall time은 더 심합니다.)
* pandas: 0.9ms, modin: 6ms, vaex: 1.9ms
이번엔 groupby 연산을 비교하겠습니다.
%time pandas_df.groupby(['column1','column2','column3']).sum() %time dask_df.groupby(['column1','column2','column3']).sum() %time modin_df.groupby(['column1']).sum() %time vaex_df.groupby(by=['column1','column2','column3'],agg={'column4': vaex.agg.sum('column4'),'column5': vaex.agg.sum('column5'),'column6': vaex.agg.sum('column6'),'column7': vaex.agg.sum('column7'),'column8': vaex.agg.sum('column8')}) |
pandas: CPU times: user 2.84 s, sys: 1.33 s, total: 4.17 s Wall time: 4.01 s
dask: CPU times: user 21.8 ms, sys: 261 µs, total: 22.1 ms Wall time: 19.7 ms
modin: CPU times: user 857 ms, sys: 536 ms, total: 1.39 s Wall time: 3.68 s
vaex: CPU times: user 6.93 s, sys: 3.09 ms, total: 6.94 s Wall time: 1.13 s
*modin의 경우 여러행 groupby는 베타 버전으로 에러가 발생하여 단일행 groupby를 진행했습니다.
*vaex의 경우 다른 라이브러리와 달리 일일이 값을 할당해줬습니다.
이 때 dask는 또 결과값을 보여주지 않습니다.
결과값을 보고 싶다면 뒤에 .compute()를 붙여주면 계산을 합니다.
%time dask_df.groupby(['REG_YYMM','CARD_SIDO_NM','STD_CLSS_NM']).sum().compute() |
CPU times: user 683 ms, sys: 181 ms, total: 864 ms Wall time: 6.2 s
modin의 경우 직접 비교가 불가능하지만 대략 2.5배 정도 추가로 가정하겠습니다.
cpu time: dask < pandas < modin < vaex
wall time: dask < vaex < pandas < dask(compute) < modin
* 실험 결과
매우 의미있는 결과를 내진 못 했지만, 나름 정리해보겠습니다.
1. 파일을 읽는 데는 대부분의 라이브러리가 pandas 보다 효율적입니다.
2. vaex의 경우 문법이 다른 것 뿐만 아니라 예시 수준의 데이터에 대해선 크게 효과를 보지 못 했습니다.
(string에 대한 실험도 필요해보입니다.)
3. dask의 경우 lazy compute를 활용하기 때문에 필요할 때만 연산을 사용하여 잘 사용하면
효율적으로 쓸 수 있을 것이란 걸 보여줍니다.
4. modin의 경우 불안정한(?) dask 버전을 사용해서 그런 지는 모르겠지만, groupby에서 아쉬운 모습을 보여줬습니다.
groupby와 같은 문제들이 해결된다면 다시 비교를 해봐야 정확할 것 같습니다.
시간이 된다면 다음에 좀 더 의미있는 비교를 해봐야 할 것 같습니다...
참고
speakerdeck.com/ianozsvald/flying-pandas-modin-dask-and-vaex
'Programming > Tip&Informaion' 카테고리의 다른 글
[DataScience] DB SQL과 연동하기 (0) | 2020.07.17 |
---|---|
[scikit-learn] 사이킷런의 regression (0) | 2020.07.10 |
[환경구축] 아치 리눅스, venv 부터 jupyter notebook 까지 (1) | 2020.06.26 |
A/B 테스트 (0) | 2020.05.13 |
[java/db/실수] prepareStatement에서 setString 후 결과가 없는 문제 (0) | 2020.01.07 |