안녕하세요
K-인사이트입니다.
데이터를 분석하기 위해 여러 데이터를 다양한 방법으로 합치는 기술은 매우 필수적입니다. 분석의 과정은 오래걸리지 않으나 이를 합치고 자르고 다시 이어붙이는 과정에는 상당한 시간과 데이터에 대한 이해가 필요합니다. 프로그래밍 분야에서 SQL 영역에 속합니다. 예를들어 여러개 파일로 분할된 CSV 파일을 하나의 데이터프레임으로 만들 수 있습니다. 그리고 서로 다른 두 데이터프레임을 열을 기준으로 결합 할 수도 있습니다. 이 글에서는 기본적이지만 가장 중요한 데이터를 결합하는 다양한 방법에 대해서 알아보도록 하겠습니다.
파이썬 환경 구축
pipenv 를 통해서 간편하게 원하는 파이썬 환경을 구성할 수 있습니다. 관련된 내용은 아래의 링크를 참고해주세요.
판다스(Pandas), 데이터 프레임을 행 방향으로 합치기(유니언)
판다스를 설치하지 않았다면 pip install pandas 를 통해서 설치합니다. 데이터 프레임을 행 방향으로 합친다는 의미는 동일한 종류의 데이터를 세로 방향으로 늘리는 것을 말합니다. 아래의 간단한 예시를 통해서 쉽게 이해할 수 있습니다.
아래의 그림은 회원정보를 보관하는 분리된 테이블 2개를 제시합니다. 두 테이블은 동일한 속성의 정보를 담고 있어 행 방향으로 합칠 수 있습니다.
즉, 아래 그림과 같이 세로 방향으로 데이터를 늘리게 되며 두 테이블은 하나의 테이블로 관리됩니다.
이 과정을 파이썬 코드를 통해서도 손쉽게 할 수 있습니다. pandas 는 데이터프레임(DataFrame)을 합치는 함수로 concat 함수를 제공합니다. 두 파일은 동일한 데이터를 다루기 때문에 데이터 손실 없이 결합이됩니다.
tr1 = pd.read_csv('./day1/transaction_1.csv')
tr2 = pd.read_csv('./day1/transaction_2.csv')
tr = pd.concat(
[tr1, tr2], # 합칠 데이터프레임들을 배열로 입력
ignore_index=True # 인덱스를 재설정하는 옵션
)
tr.head()
판다스(Pandas) 응용 패턴, for 루프를 이용한 여러 데이터프레임 합치기
앞서 행으로 데이터를 합치는 방법은 실무에서 수백여개의 파일을 이용해 합치는 작업을 수행합니다. 따라서, 수많은 데이터 파일들을 읽어들여서 행으로 합치는 코드가 필요합니다. 하지만 여기서 메모리의 효율성을 고려하는 태도가 필요합니다. 수백여개 파일을 잘못된 방법으로 합치게되면 메모리 크기가 커지게되어 다음에 올 분석작업을 수행하는데 있어 방해가 될 수 있습니다.
아래의 코드는 for 루프를 통해서 파일들의 목록을 불러오고 데이터프레임을 생성한 뒤에 배열에 추가합니다. 루프가 완료되면 판다스가 제공하는 concat 함수를 통해서 하나의 데이터 프레임으로 결합합니다.
import pandas as pd
import os
dir_path = 'some/dir/path'
df_list = [] # 빈 배열을 선언
for fname in os.listdir(dir_path): # 파일 목록을 나열하는 루프
df_temp = pd.read_csv(os.path.join(dir_path, fname)) # 데이터 읽어옮
df_list.append(df_temp) # 배열에 데이터 프레임을 추가
df = pd.concat(df_list) # 배열에 저장된 데이터프레임들을 결합
판다스, 길이가 다른 데이터 합치기
여러 칼럼을 서로 다른 데이터에서 가져와 결합을 하는 경우를 떠올려 봅시다. 출처 A에서 가격 정보를 추출하고 출처 B에서 면적정보를 가져옵니다. 그리고 출처 C에서 타입에 대한 정보를 가져온다고 해보겠습니다. 이들 데이터들의 길이가 다르다고 할때 어떻게 하나의 데이터로 합칠까요?
비결은 판다스의 범주에서 생각하는 것이 아닌 파이썬 코딩의 관점에서 생각하는 것입니다. 출처 A,B,C에서 얻는 데이터는 배열(array)타입의 데이터일 것입니다. 따라서, 세 데이터를 별도의 리스트 변수로 선언하고 딕셔너리 타입으로 초기화를 수행합니다. 판다스는 딕셔너리 데이터를 데이터 프레임으로 변환하는 from_dict 함수를 가지고 있습니다. 이를 통해서 데이터 프레임으로 전환하면 하나의 DataFrame이 됩니다.
하지만, 각 세종류의 데이터는 행이 아니라 열입니다. 따라서 행과 열을 바꾸어주는 transpose 함수를 통해서 행과 열을 바꿀 수 있습니다. 이 과정을 통해서 별도의 데이터를 불러와서 칼럼으로 지정하는 데이터 프레임을 생성할 수 있게 됩니다.
import pandas as pd
a = [i for i in range(7)]
b = [i for i in range(9)]
c = [i for i in range(4)]
dic = {
'A' : a,
'B' : b,
'C' : c
}
res = pd.DataFrame.from_dict(dic, orient='index')
res
# 0 1 2 3 4 5 6 7 8
# A 0 1 2 3 4.0 5.0 6.0 NaN NaN
# B 0 1 2 3 4.0 5.0 6.0 7.0 8.0
# C 0 1 2 3 NaN NaN NaN NaN NaN
res = res.transpose()
res
# A B C
# 0 0.0 0.0 0.0
# 1 1.0 1.0 1.0
# 2 2.0 2.0 2.0
# 3 3.0 3.0 3.0
# 4 4.0 4.0 NaN
# 5 5.0 5.0 NaN
# 6 6.0 6.0 NaN
# 7 NaN 7.0 NaN
# 8 NaN 8.0 NaN
위 예시에서 주의할 점은 길이가 다른 데이터를 결합함에 따라 NaN 으로 표기되는 데이터가 존재할 수 있습니다. 이를 결측치라고 부르며 fillna 함수를 통해서 0 또는 여러분이 원하는 값으로 채울 수 있습니다. 아래의 그림을 참고해주세요.
판다스, 열 데이터 합치기 (Join)
지금까지는 단순히 세로로 데이터를 늘렸다면 이번에는 서로 다른 두 테이블을 결합하는 과정을 알아보겠습니다. 흔히 데이터베이스를 작업할 때 키(Key)값을 매개로 두 테이블을 결합하는 작업들이 빈번하게 일어납니다. 이를 조인(Join) 또는 병합(Merge)라고 부릅니다. 아래의 그림을 통해서 간단하게 이해할 수 있습니다.
위 그림은 회원정보와 구매정보 데이터를 간략화한 내용입니다. 회원정보와 구매정보는 1:N 관계를 가지므로 두 테이블을 열 방향으로 결합하려면 구매정보 테이블을 기준으로 회원정보의 열을 붙이는 작업이 필요합니다.
실제 코드를 보면 아래와 같습니다. 판다스는 열 합치기를 지원하는 merge 함수를 제공합니다. 이 함수는 기준이 되는 데이터프레임에 다른 데이터프레임의 칼럼들을 결합합니다. 이때 on 옵션을 통해서 key 값을 지원하며 이 key 값은 앞서 예시의 "아이디"와 같은 고유값을 의미합니다. how 옵션을 통해 left, right 등의 join 방식을 선택할 수 있습니다.
tr_detail = pd.concat([tr1_detail, tr2_detail], ignore_index=True)
tr_detail.head()
# detail_id transaction_id item_id quantity
# 0 0 T0000000113 S005 1
# 1 1 T0000000114 S001 1
# 2 2 T0000000115 S003 1
# 3 3 T0000000116 S005 1
# 4 4 T0000000117 S002 2
join_data = pd.merge(
tr_detail, # 기준이 되는 DataFrame
tr[['transaction_id', 'payment_date', 'customer_id']], # 열을 붙일 DataFrame
on='transaction_id', # key 가 되는 칼럼
how='left' # left-join 방식을 사용
)
join_data.head()
# detail_id transaction_id item_id quantity payment_date customer_id
# 0 0 T0000000113 S005 1 2019-02-01 01:36:57 PL563502
# 1 1 T0000000114 S001 1 2019-02-01 01:37:23 HD678019
# 2 2 T0000000115 S003 1 2019-02-01 02:34:19 HD298120
# 3 3 T0000000116 S005 1 2019-02-01 02:47:23 IK452215
# 4 4 T0000000117 S002 2 2019-02-01 04:33:46 PL542865
Left Join 은 왼쪽 테이블을 기준으로 A, B 테이블을 비교해서 B테이블에서 조인 조건에 해당하는 값이 있다면 그 값을 가져오고 값이 없다면 NaN 값을 가져옵니다. 아래의 그림을 통해 Left Join 의 특성을 쉽게 이해할 수 있습니다.
이상입니다.
K-인사이트 올림.
'프로그래밍 > 데이터분석' 카테고리의 다른 글
데이터분석, 파이썬 CSV 파일 불러오기, 경로 오류 처리, 한글깨짐(utf-8) 보정 (feat. numpy, pandas) (102) | 2024.04.22 |
---|---|
Jupyter Notebook, No Attribute 에러 해결을 위한 모듈 리로드(reload) 방법 (53) | 2024.04.01 |
데이터분석, TLT 와 미국 기준금리(Fedfunds)를 그래프로 그리기 (7) | 2024.02.04 |