결론부터 보실 분은 여기로 >> https://github.com/yc-song/dbmerge
0. 들어가며
아래와 같은 별개의 엑셀 파일/시트를 하나로 합친다고 합시다. 행의 순서가 통일되어 있어 별로 어려운 일이 아닐 것 같습니다.
1.xlsx | |
이름 | 나이 |
라이언 | 22 |
포로리 | 33 |
도라에몽 | 19 |
아라찌 | 24 |
2.xlsx | |
이름 | 나이 |
비둘기 | 35 |
어피치 | 49 |
김강철 | 11 |
하지만 다음과 같이 행이 같지만 순서가 뒤죽박죽인 엑셀 파일이 추가된 상황이라면 어떨까요?
3.xlsx | |
나이 | 이름 |
43 | 김구구 |
32 | 이구구 |
29 | 박구구 |
11 | 구구구 |
심지어 행의 항목도 이상한게 추가된 엑셀 시트까지 합쳐야 한다면?
4.csv | ||
나이 | 이름 | 성별 |
29 | 구구콘 | M |
32 | 슈퍼콘 | F |
29 | 손흥민 | F |
15 | 슈퍼콘 | M |
해외 문서까지 합쳐져서 Name열의 내용을 이름 열 밑으로 합쳐야 하는 상황이라면?
5.xlsx | ||
Name | Age | Gender |
Nabi | 34 | M |
Bobettau | 29 | F |
周星馳 | 50 | M |
孫 正義 | 62 | M |
블로그 포스팅을 위해 만들어낸 작위적인 상황 같지만; 실제로 회사에서 이와 유사한 상황에 대처해야 했습니다.
하지만 우리에게는 노가다를 견뎌낼 수 있는 강인한 체력 컴퓨터가 있으니 찬찬히 살펴보도록 합시다.
1. 위의 1,2,3 파일을 하나로 합치는 경우
우선 다음과 같은 엑셀 파일을 생성했습니다.
위의 테이블과 같은 내용의 파일입니다. 이름, 나이 열이 뒤죽박죽이었던 위 파일들을 아래와 같이 합치고자 합니다.
소스코드 및 설명
위의 1,2,3 엑셀 파일을 프로젝트 밑의 rawdata폴더에 저장했습니다. 코드는 다음과 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import pandas as pd
import glob
import xlrd
import openpyxl
#우선 모든 자료들을 raw data folder에 저장
all_data = pd.DataFrame()
all_data1 = pd.DataFrame()
for f in glob.glob("rawdata/*.xlsx"): #rawdata 디렉토리에 있는 xlsx파일들 불러옴
df=pd.read_excel(f, sheet_name=None)
all_data1 = pd.concat(df, ignore_index=True)
all_data=all_data.append(all_data1,ignore_index=True)
print(all_data)
all_data.to_excel('합본.xlsx',encoding='utf-8-sig') #저장
#엑셀로 저장하는게 오래 걸릴 때에는, csv로 저장할 수도 있습니다.
#all_data.to_csv('합본.csv',encoding='utf-8-sig')
|
cs |
위의 과정을 도식화하면 다음과 같이 정리할 수 있습니다.
만약 주어진 파일 중에 csv가 있다면, 아래와 같이 csv용 for문을 추가할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import pandas as pd
import glob
import xlrd
import openpyxl
#우선 모든 자료들을 raw data folder에 저장
all_data = pd.DataFrame()
all_data1 = pd.DataFrame()
for f in glob.glob("rawdata/*.xlsx"): #rawdata 디렉토리에 있는 xlsx파일들 불러옴
df=pd.read_excel(f, sheet_name=None)
all_data1 = pd.concat(df, ignore_index=True)
all_data=all_data.append(all_data1,ignore_index=True)
#######추가######
for f in glob.glob("rawdata/*.csv"): #csv 불러옴
df=pd.read_csv(f,index_col=None, header=0, encoding='UTF8')
all_data1 = pd.concat([df], ignore_index=True)
all_data=all_data.append(all_data1,ignore_index=True)
#################
all_data.to_excel('합본.xlsx',encoding='utf-8-sig') #저장
#엑셀로 저장하는게 오래 걸릴 때에는, csv로 저장할 수도 있습니다.
# all_data.to_csv('합본.csv',encoding='utf-8-sig')
|
cs |
2. 위의 상황에 덧붙여, 네번째 파일 (성별 column 존재)이 추가된 경우
일부러 파일 포맷을 csv로 해보았습니다.
위의 코드를 그대로 쓰면 됩니다. 결과는 다음과 같습니다.
1,2,3번 엑셀 파일에는 성별 정보가 없어서, 해당 행에는 성별 열을 비워둔 것을 확인할 수 있습니다.
3. 마지막으로, 열의 이름이 다른 다섯번째 파일이 추가된 경우 (최종 코드)
Name을 이름 행에, Age를 나이 행에, Gender를 성별 행에 합치는 경우입니다. df의 type은 dictionary이기 때문에, Key를 일일이 바꿔주는 방식으로 해결할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import pandas as pd
import glob
import xlrd
import openpyxl
#우선 모든 자료들을 raw data folder에 저장
all_data = pd.DataFrame()
all_data1 = pd.DataFrame()
for f in glob.glob("rawdata/*.xlsx"): #rawdata 디렉토리에 있는 xlsx파일들 불러옴
df=pd.read_excel(f, sheet_name=None)
all_data1 = pd.concat(df, ignore_index=True)
######추가#####
all_data1.rename(columns={"Gender":"성별","Age":"나이","Name":"이름"},inplace=True) #추가된 부분
##############
all_data=all_data.append(all_data1,ignore_index=True)
for f in glob.glob("rawdata/*.csv"): #csv 불러옴
df=pd.read_csv(f,index_col=None, header=0, encoding='UTF8')
all_data1 = pd.concat([df], ignore_index=True)
all_data1.rename(columns={"Gender":"성별","Age":"나이","Name":"이름"},inplace=True)
all_data=all_data.append(all_data1,ignore_index=True)
all_data.to_excel('합본.xlsx',encoding='utf-8-sig') #저장
# all_data.to_csv('합본.csv',encoding='utf-8-sig') #csv로 저장
|
cs |
중간에 all_data1.rename으로 시작되는 부분이 key를 바꿔주는 부분입니다. 위 코드대로 하면 다음과 같이 1~5번 파일이 제대로 합쳐진 것을 확인할 수 있습니다.
4. 마치며
위 코드를 통해, 3개월~1년마다 데이터 내용이 변하고, 방대한 양의 데이터 시트를 자동으로 합칠 수 있었습니다. (합쳤는데 csv가 23MB될 정도로 노가다 절대 불가능한 파일... ㅎ.ㅎ)
오타를 비롯 수정이 필요한 부분이 있으면 지적 부탁드립니다.
https://github.com/yc-song/dbmerge
concat함수에 대해 더 잘 알 수 있는 곳:
https://rfriend.tistory.com/256
https://classicismist.blogspot.com/2018/10/pandas-concat-dataframe-how-to-merge.html
Reference
https://stackoverflow.com/questions/28669482/appending-pandas-dataframes-generated-in-a-for-loop
'프로그래밍 이야기 > Python' 카테고리의 다른 글
Python으로 Neural Net 체험하기 (0): 단층 신경망 최적화 (0) | 2020.05.02 |
---|---|
Python으로 구분구적법 알아보기 (0) | 2020.04.30 |