목차
많은 양의 데이터를 이동하거나 보관할 때 주로 이들을 압축하며, zip과 tar 확장자가 대표적이다. 최근 시그널 프로세싱에 관련된 데이터 분석을 하면서 많은 실험 데이터를 다루게 되었다. 이것들은 실험의 조건에 따라 여러 그룹으로 나누어져 있고, 각 조건마다 수십 개의 파일들이 있어 데이터를 옮기는 데만 상당히 많은 시간이 걸리게 되었다. 클라우딩 스토리지를 사용하면 좋겠지만, 아직 그 단계의 시스템이 구축된 것이 아니어서 일단 압축 파일의 형태로 데이터를 옮기고 읽어 들이기로 하였다.
이번 포스팅에서 python에서 zip 파일의 압축을 풀고 데이터를 읽는 법에 대해서 정리해보았다. 또한, 압축을 풀지 않고 내부 파일의 데이터를 로딩하는 방법에 대해서도 정리했다. 특히, 후자의 경우는 디스크 사용량을 줄이거나 데이터 관리를 하는데 있어 유용할 것으로 생각된다.
우선 필요한 모듈들을 import한다. 이중 zip 파일을 다루는 파이썬 모듈은 ZipFile이다.
import os
import io
import zipfile
from zipfile import ZipFile
import pandas as pd
import requests
import tensorflow as tf
포스팅의 과정을 따라갈 수 있게 하기 위해 실제로 다섯개의 파일이 압축되어 있는 VSB Power Line Fault Detection dataset 를 이용해보자. 이 링크로부터 zip 파일로 압축되어 있는 데이터를 다운로드할 수 있다. 아래와 같이 'vsb-power-line-fault-detection.zip' 이 생긴 것을 확인한다.
!ls
현재 디렉토리에 있는 zip 파일을 출력해본다.
zipfiles = [ file for file in os.listdir() if file.endswith('zip')]
print(zipfiles)
압축 풀기
압축된 파일 리스트 확인하기
압축을 풀기전 zip 파일에 어떤 파일들이 묶여 있는지 확인할 수 있다. zipfile의 namelist()라는 메서드를 이용한다. 이 과정은 압축을 푸는 것이 아니라, 단지 zip 파일에 어떤 파일들이 있는지 확인하는 것이다.
with ZipFile('vsb-power-line-fault-detection.zip', 'r') as zipObj:
listOfFileNames = zipObj.namelist()
for fileName in listOfFileNames:
print(fileName)
압축을 풀 디렉토리를 만들고 압축 풀기
zipFile의 extractall()이라는 메서드를 이용해 압축을 풀 수 있고, input argument로 압축을 풀 디렉토리 이름을 줄 수 있다. 그러면 압축 해제된 파일들이 지정된 디렉토리에 위치하게 된다. 다음과 같이 실행하여 vsb-power-line-fault-detection.zip 파일을 vsb-power-line-fault-detection이라는 디렉토리에 압축을 풀어준다.
with ZipFile('vsb-power-line-fault-detection.zip', 'r') as zipObj:
zipObj.extractall('vsb-power-line-fault-detection')
!ls
ls로 디렉토리가 만들어진 것을 확인하고, 이 디렉토리 안의 압축이 풀린 파일들을 확인한다.
# 압축이 풀린 5개의 파일이 생긴것을 볼 수 있다.
os.listdir('vsb-power-line-fault-detection/')
원하는 특정 파일만 축출하기
위와 같이 extractall()을 이용하면 모든 파일의 압축을 풀 수 있다. 반면, 원하는 파일만 골라서 축출할 수 있는 방법이 있다.
예를 들어 위의 다섯개의 파일 중 csv파일만 필요하다고 해보자. 다음과 같이 파일명을 확인하고 그중에 csv를 확장자로 가지는 파일만 extract()하는 것이다. 이때도 역시 축출한 파일을 놓을 디렉토리를 만들 수 있다. CSV_files라고 해보자.
with ZipFile('vsb-power-line-fault-detection.zip', 'r') as zipObj:
listOfFileNames = zipObj.namelist()
for fileName in listOfFileNames:
if fileName.endswith("csv"):
zipObj.extract(fileName, 'CSV_files')
ls로 CSV_files 디렉토리가 만들어진 것을 확인한다.
!ls
os.listdir로 CSV_files 디렉토리의 파일을 확인한다. 의도한 대로 CSV 포맷의 파일 세 개만 압축이 풀여 있다.
os.listdir("CSV_files")
압축을 풀지 않고 데이터 로딩하기
지금까지 python의 zipFile의 extractall()과 extract() 메소드를 이용해 압축 파일을 추출하는 법을 알아보았다. 이번에는 압축을 풀지 않고 zip 파일 내의 파일들을 읽어 데이터로 로딩하는 방법에 대해서 알아보도록 하자. 이렇게 한다면, 분석하기 위한 데이터를 항상 압축된 형태로 보관할 수 있어 디스크 사용량 관리와 더불어 많은 종류의 데이터를 관리하는 데도 큰 도움이 된다.
단일 압축 파일 읽기
우선 하나의 csv파일이 zip으로 압축된 경우를 다뤄보자. 예제 파일로 jena climate이라는 데이터셋을 골랐고, 아래의 링크에서 csv.zip파일을 내려받을 수 있다.
url = 'https://storage.googleapis.com/tensorflow/tf-keras-datasets/jena_climate_2009_2016.csv.zip'
- url로부터 압축 파일 내려받기 : request 모듈
requests 모듈을 이용해 아래와 같이 파일을 다운로드할 수 있다.
def download(url):
get_response = requests.get(url)
file_name = url.split("/")[-1]
with open(file_name, 'wb') as f:
for chunk in get_response.iter_content(chunk_size=1024):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
print("file name to be downloaded: {}".format(file_name))
print("is downloaded? {}".format(os.path.exists(file_name)))
download(url)
!ls
pandas.read_csv는 zip파일로 된 csv파일도 읽는다. 아래와 같이 데이터를 확인한다.
pd.read_csv('jena_climate_2009_2016.csv.zip')
- url로부터 압축 파일 내려받기 : tensorflow 이용
이번에는 tensorflow를 이용해 url 데이터를 받을 수 있다.
zip_path = tf.keras.utils.get_file(
origin='https://storage.googleapis.com/tensorflow/tf-keras-datasets/jena_climate_2009_2016.csv.zip',
fname='jena_climate_2009_2016.csv.zip',
extract=False)
zip_path
pd.read_csv(zip_path)
압축된 여러 파일을 읽기
이번에는 여러 csv파일이 압축된 zip 파일로부터 각각의 csv 데이터를 압축을 풀지 않은 채로 로딩해보자. 'vsb-power-line-fault-detection.zip'에서 세 개의 csv파일을 압축 해제 없이 읽어 들인다.
from io import BytesIO
data_filename = []
data=[]
with ZipFile('vsb-power-line-fault-detection.zip', 'r') as zipObj:
listOfFileNames = zipObj.namelist()
for fileName in listOfFileNames:
if fileName.endswith('csv'):
print(fileName)
zipRead = zipObj.read(fileName)
curr_df = pd.read_csv(BytesIO(zipRead))
data.append(curr_df)
data_filename.append(fileName)
data라는 리스트에 저장했다. 이 리스트에 세 개의 dataframe이 더해진 것을 확인한다.
print("the number of loaded csv files : {}".format(len(data)))
각각의 데이터를 출력하여, 데이터가 잘 읽어 들여졌는지 확인한다.
for filename, d in zip(data_filename, data):
print("--------------------------")
print(filename)
display(d.head(5))
참고한 링크
- Python: How to create a zip archive from multiple files or Directory
- Python: How to unzip a file | Extract Single, multiple or all files from a ZIP archive
- (stackoverflow) Reading csv zipped files in python
'Programming > Python' 카테고리의 다른 글
[Python] Pandas groupby 결과를 list의 dictionary로 바꾸기!! (0) | 2022.05.02 |
---|---|
[Pandas] UnicodeDecodeError: 'utf-8' codec can't decode byte 해결방법 (1) | 2022.04.13 |
[Python] pandas 파일 로딩 속도 비교 (CSV vs. Pickle 포맷) (0) | 2021.06.02 |
[Python] Pandas 'settingWithCopyWarning' 경고 메세지 없애기 (0) | 2021.05.09 |
[Python] Pandas sorting (오름/내림 정렬) 하기 (0) | 2021.05.01 |
댓글