1차 기술세미나(2024.01.03 발표)
주제 : 데이터 처리를 위한 Pandas와 Numpy의 활용
목차
1. 데이터에 대한 이해
2. Pandas, Numpy 소개
3. Pandas 실제 사용 예시
4. Pandas 성능 향상을 위한 tip
1. 데이터에 대한 이해
현재 데이터는 폭발적으로 증가하는 추세
데이터의 크기가 커질수록 데이터를 분석하기 어려워짐.
=> Numpy와 Pandas는 데이터를 '효율적'으로 분석하기 위한 패키지
2. Pandas, Numpy 소개
- Pandas란 무엇인가?
정의 : 데이터 처리를 위한 Python 라이브러리
강점 : 대용량 데이터 처리 가능, 데이터 구조화 기능, 데이터 조작 기능, 데이터 시각화 기능
- Numpy란 무엇인가?
정의 : 행렬 및 대규모 다차원 배열을 처리하는 Python 연산 라이브러리
강점
1. ndarray 배열로 자료를 저장, 편리한 수치해석을 지원
2. 선형 대수 기반으로 배열을 작성하여 빠른 연산을 지원
3. 타 패키지와 연동할 수 있는 높은 호환성
4. 빅데이터 처리에 유용한 기능
- 왜 Pandas와 Numpy를 사용하는가?
메모장 : 메모리 부족, 성능적 제한, 가시성 부족, 제한된 기능
엑셀 : 메모리 부족, 최대 열 제한, 셀 형식 제한, 제한된 기능
Pandas + Numpy : 높은 메모리 효율성, 가시적인 데이터 구조, 분석 및 조작 기능, 유연하고 뛰어난 연산
+
활발한 커뮤니티, 지속적인 업데이트 지원
● 함수의 기능
1. info()
데이터프레임을 구성하는 행과 열의 크기, 열의 이름, 열을 구성하는 값의 자료형 등 전체적인 정보를 출력
2. describe()
수치적으로 계산할 수 있는 데이터(int, float 등)에 대한 평균, 최소/최대, 표준편차, 분산 등 전반적인 기술 통계를 제공
3. head(N)
데이터프레임의 처음 N(기본값 5)개의 행을 가져와 출력
(어떤 값이 들어있는지 대략적으로 확인 가능)
4. tail(N)
데이터프레임의 마지막 N(기본값 5)개의 행을 가져와 출력
(어떤 값이 들어있는지 대략적으로 확인 가능)
- Pandas 버전 성능 비교
1. describe() 함수
Pandas v1.5.3(왼) 과 Pandas v2.1.4(오른)
Pandas v1.5.3은 CPU 시간 : 2.08s, 실행 시간 : 2.08s
Pandas v2.1.4는 CPU 시간 : 1.53s, 실행 시간 : 1.57s
2. isNa() 함수
Pandas v1.5.3(왼) 과 Pandas v2.1.4(오른)
Pandas v1.5.3은 CPU 시간 : 15.6ms, 실행 시간 : 19.2ms
Pandas v2.1.4는 CPU 시간 : 0ns, 실행 시간 : 10ms
3. str.contains() 함수
Pandas v1.5.3(왼) 과 Pandas v2.1.4(오른)
Pandas v1.5.3은 CPU 시간 : 3.67s, 실행 시간 : 3.7s
Pandas v2.1.4는 CPU 시간 : 2.69s, 실행 시간 : 2.7s
- Pyarrow 이용해서 csv, parquet 읽을 때의 성능 차이
pyarrow : 메모리 내 분석을 위한 개발 플랫폼인데, 빅데이터를 빠르게 처리하고 이동할 수 있도록 하는 일련의 기술을 제공하는 라이브러리를 파이썬 PyArrow를 통해 구현가능함. => 시간 절약에 도움.
1. csv
2. parquet
- Pandas 실제 사용 예시
사용 데이터 : 서울 열린데이터 광장 - 서울시 버스노선별 정류장별 승하차 인원 정보
1. 월별 데이터 합침 => 연도 버스 데이터
2. '평일', '주말' 데이터 구분
(1) 사용일자를 datetime형으로 변환
(2) Datetime형인 사용일자를 이용해서 weekday column을 만듦. (0:월, 1:화, 2:수, 3:목, 4:금, 5:토, 6:일)
(3) 평일, 주말 데이터 구분 (평일 : data_wd, 주말 : data_we)
(4) 평일, 주말 승하차 총 승객 수의 평균
하루 총 승객수 |
승차 | 하차 |
평일 | 4,759,925 | 4,651,524 |
주말 | 3,074,955 | 3,004,367 |
=> 승차, 하차 모두 총 승객수가 평일에 더 많다고 판단 가능
3. 승하차 총 승객 수 최대, 최소 노선 번호
- 승차 총 승객 수
143번이 최대, N840번이 최소
- 하차 총 승객 수
마찬가지로, 143번이 최대, N840번이 최소
- 143번 버스 데이터 분석
경기여고, 휘문고, 경기고, 청담고 등 강남권 주요 고교들을 여럿 지나므로 평일에는 거의 학생 셔틀버스 수준의 역할을 함.
=> 제일 큰 이유라고 추측 가능
- N840번 버스 데이터 분석
N840 2022년 1월 1일까지 운행 후 폐지됨.
=> 승, 하차 총 승객 수 제일 적음
4. 계절별로 분석해보기
(1) '사용일자'로 '사용월' 컬럼 생성
(2) '사용월'로 '계절' 컬럼 생성
5. 버스 종류 구분(시내, 마을, 심야)
- 노선번호 맨 앞이 N → 심야버스 Ex) N61
- 노선번호 앞 두 글자가 10진수 → 시내버스 Ex) 5535
- 10진수 X → 마을버스 Ex) 금천05
(시내 버스)
(마을버스)
(야간 버스)
4. Pandas 성능 향상을 위한 Tip
- parquet, pickle, csv 소개 및 특징
(1) parquet
소개 : 효율적인 데이터 스토리지와 검색을 지원하도록 설계된 컬럼 기반의 오픈소스 데이터 파일 형식
특징
● 프로그래밍 언어에 구애받지 않음.
● 컬럼 기반 형식으로 구성됨.
● 데이터 압축 / 해제의 효율이 매우 높음.
● 고급 중첩 데이터 구조 지원
(2) pickle 소개 및 특징
소개 : 파이썬에서 사용하는 Dict, List, Class 등의 자료형을 변환없이 그대로 파일로 저장하고 불러오는 모듈
특징
● 파이썬의 모든 데이터 객체를 저장할 수 있음.
● 파일을 읽을 때 한 줄씩 읽어들임.
● List와 같은 데이터 객체를 입출력할 때 유용함.
(3) csv 소개 및 특징
소개 : 쉼표(,)로 구분한 데이터를 저장할 때 사용하는 데이터 형식
특징
● 엑셀로 자료를 불러와 전산 작업이 가능함.
● 원형 그대로 가공하기 좋은 데이터 형식
● 간편하게 생성 가능
● 파이썬으로 불러와 복잡한 연산 수행 가능
- parquet, pickle, csv 읽기 성능 비교
(1) parquet
parquet 자원 사용량 | |
저장용량 | 229.94 MB |
사용 메모리 | 8855.90 MiB |
최근 증감률 | 1925.52 MiB |
CPU 시간 | 6.86s |
소요시간 | 3.84 s |
(2) pickle
pickle 자원 사용량 | |
저장용량 | 1037.88 MB |
사용 메모리 | 8903.29 MiB |
최근 증감률 | 2175.92 MiB |
CPU 시간 | 3.11 s |
소요시간 | 3.88 s |
(3) csv
csv 자원 사용량 | |
저장용량 | 1602.18 MB |
사용 메모리 | 10505.88 MiB |
최근 증감률 | 3773.94 MiB |
CPU 시간 | 16.3 s |
소요시간 | 16.9 s |
- parquet, pickle, csv 쓰기 성능 비교
(1) parquet
parquet 자원 사용량 | |
저장용량 | - |
사용 메모리 | 3260.83 MiB |
최근 증감률 | 1427.48 MiB |
CPU 시간 | 8.27 s |
소요시간 | 8.93 s |
(2) pickle
pickle 자원 사용량 | |
저장용량 | - |
사용 메모리 | 2876.74 MiB |
최근 증감률 | 822.37 MiB |
CPU 시간 | 3.66 s |
소요시간 | 4.41 s |
(3) csv
csv 자원 사용량 | |
저장용량 | - |
사용 메모리 | 1838.21 MiB |
최근 증감률 | 5.16 MiB |
CPU 시간 | 31.8 s |
소요시간 | 32.6 s |
- parquet, pickle, csv 성능 비교
csv가 메모리 사용량, 시간, 하드 저장 용량 부분에서 비효율적이라는 것 판단할 수 있음.
데이터 저장, 처리의 효율성 고려할 때, pickle은 빠르고 편리하게 사용가능하지만, python 환경에서만 가능함.
저장 용량 효율과 호환성 고려하면, parquet이 더 유리할 수 있음.
- 사용하는 메모리 줄이기
먼저, '시도코드'로 테스트.
기존 데이터 타입 : int64
('시도코드'를 category(범주형 변수)로 변환한 후 메모리 사용량 비교)
메모리 사용량을 비교해보면
메모리 사용량 | 순위 | |
시도명 | 223,980,090 | 1 |
시도코드 | 19,732,328 | 2 |
시도코드_cat | 2,467,233 | 3 |
두 번째로, 상권업종대분류코드로 테스트
메모리 사용량을 비교해보면
메모리 사용량 | 순위 | |
상권업종대분류명 | 241,988,968 | 1 |
상권업종대분류코드 | 145,525,919 | 2 |
상권업종대분류코드_cat | 2,467,431 | 3 |
이번에도 범주형 변수를 사용했을 때, 메모리 사용량이 제일 적음.
=> 메모리 사용량을 줄이기 위해서 범주형 변수 사용을 고려할 수 있음.
- 다른 코드, 같은 결과 성능 비교
데이터 : 동해 시에 있는 상권 추출하는 코드 비교 (5297건)
(1) List Comprehension 실행 결과
List Comprehension | |
저장용량 | - |
사용 메모리 | 3704.97 MiB |
최근 증감률 | 1.84 MiB |
CPU 시간 | 2min 1s |
소요시간 | 2min 2s |
(2) pd.DataFrame.query() 실행 결과
pd.DataFrame.query() | |
저장용량 | - |
사용 메모리 | 3715.64 MiB |
최근 증감률 | 39.91 MiB |
CPU 시간 | 188 ms |
소요시간 | 718 ms |
(3) pd.DataFrame.apply() 실행 결과
pd.DataFrame.apply() | |
저장용량 | - |
사용 메모리 | 3699.14 MiB |
최근 증감률 | 23.32 MiB |
CPU 시간 | 2min 1s |
소요시간 | 2min 2s |
(4) pd.DataFrame.merge() 실행 결과
pd.DataFrame.merge() | |
저장용량 | - |
사용 메모리 | 3823.14 MiB |
최근 증감률 | 171.34 MiB |
CPU 시간 | 859 ms |
소요시간 | 1.4 s |
(5) pd.DataFrame.isin() 실행 결과
pd.DataFrame.isin() | |
저장용량 | - |
사용 메모리 | 3743.39 MiB |
최근 증감률 | 68.70 MiB |
CPU 시간 | 1.2 s |
소요시간 | 1.78 s |
(6) np.isin() 실행 결과
np.isin() | |
저장용량 | - |
사용 메모리 | 3682.29 MiB |
최근 증감률 | 5.11 MiB |
CPU 시간 | 2min 11s |
소요시간 | 2min 12s |
(총 실행 결과 비교)
pandas dataframe 내장 함수 | ||||||
query() | apply() | merge() | isin() | np.isin() | LC | |
저장용량 | - | - | - | - | - | - |
사용 메모리 (MiB) |
3715.64 | 3699.14 | 3823.14 | 3743.39 | 3682.29 | 3704.97 |
최근 증감률 (MiB) |
39.91 | 23.32 | 171.34 | 68.70 | 5.11 | 1.84 |
CPU 시간 | 188 ms | 2min 1s | 859 ms | 1.2 s | 2min 11s | 2min 1s |
소요시간 | 718 ms | 2min 2s | 1.4 s | 1.78 s | 2min 12s | 2min 2s |
- DataFrame에 계속 행을 append하는 여러 방법들 성능 차이
(결과)
(실행 결과 비교)
성능 제일 높은 방법은 List_append 사용할 때,
성능 제일 낮은 방법은 Pandas_loc을 사용할 때로 차이가 약 30배 이상이 남.
=> 같은 역할을 하지만 속도 차이는 크게 날 수 있으므로 신중히 고려해서 사용해야 함.
(느낀점)
기술세미나의 의도에 잘 맞는 내용으로 구성하기 위해 팀원들과 노력했는데 좋은 결과를 얻을 수 있었다.
pandas의 함수, 사용법 정도만 알고 있었는데 parquet, pickle, csv 형식을 비교해보는 것, 같은 결과를 내지만 다른 함수를 사용한 경우 소요시간을 비교해보는 것 등을 알아보면서 시야가 넓어질 수 있었다.
이번 기회를 통해 그냥 코드를 작성하는 것에 멈추지 않고 나아가 더 효율적인 코드 작성이 어떤건지 생각하면서 개발해보고싶다는 생각이 들었다