이번 포스팅에서는 Jupyter Notebook 의 기본 사용법 중에서 

 

(1) Jupyter Notebook Cell 의 모든 결과 지우기 

    : Cell >> All Output >> Clear

(2) Jupyter Notebook 커널 새로 시작하고, 모든 Cell 실행하기

    : Kernel >> Restart & Run All

 

방법에 대해서 소개하겠습니다. 

 

 

(1) Jupyter Notebook Cell 의 모든 결과 지우기

    : Cell >> All Output >> Clear

 

 

아래에 예제로 사용할 간단한 Jupyter Notebook 을 만들어보았습니다.

x, y 객체를 프린트도 해보고, 선 그래프도 그려보았습니다.  

Jupyter Notebook Cell's Results

 

 

이제 Cell >> All Output >> Clear 순서로 메뉴를 선택해서 Cell의 모든 결과를 지워보겠습니다. 

(Clear the output of all cells in Jupyter Notebook) 

 

Jupyter Notebook - Cell - All Output - Clear

 

 

Cell >> All Output >> Clear 의 순서대로 메뉴를 선택해서 실행하면 아래처럼 Cell 의 결과가 모두 지워져서 깨끗해졌습니다. 

Jupyter Notebook - Cleared All Outputs in Cells

 

 

 

(2) Jupyter Notebook 커널 새로 시작하고, 모든 Cell 실행하기

    : Kernel >> Restart & Run All

 

위의 (1)번과는 반대로, 이번에는 Kernel 을 새로 시작(Kernel Restart)하고 모든 Cell을 새로 실행(Run All)해보겠습니다. 

(Kernel >> Restart & Run All)

Jupyter Notebook - Restart & Run All

 

 

아래와 같은 팝업 창이 뜨면 "Restart and Run All Cells" 메뉴를 선택해서 클릭해주면 됩니다. 

 

Jupyter Notebook - Restart and Run All Cells

 

 

그러면, 아래처럼 커널이 새로 시작하고, 모든 셀이 순서대로 다시 실행이 됩니다. 

Jupyter Notebook - Restart and Run All Cells - Results

 

 

 

 

이번 포스팅이 많은 도움이 되었기를 바랍니다. 

행복한 데이터 과학자 되세요. 

 

반응형
Posted by Rfriend

댓글을 달아 주세요

이번 포스팅에서는 Python을 사용해서 웹사이트에서 압축파일을 다운로드해서 압축을 해제하고 데이터셋을 합치는 방법을 소개하겠습니다. 

 

세부 절차 및 이용한 Python 모듈과 메소드는 아래와 같습니다. 

 

(1) os 모듈로 다운로드한 파일을 저장할 디렉토리가 없을 경우 새로운 디렉토리 생성하기

(2) urllib.request.urlopen() 메소드로 웹사이트를 열기 

(3) tarfile.open().extractall() 메소드로 압축 파일을 열고, 모든 멤버들을 압축해제하기

(4) pandas.read_csv() 메소드로 파일을 읽어서 DataFrame으로 만들기

(5) pandas.concat() 메소드로 모든 DataFrame을 하나의 DataFrame으로 합치기

(6) pandas.to_csv() 메소드로 합쳐진 csv 파일을 내보내기

 

 

먼저, 위의 6개 절차를 download_and_merge_csv() 라는 이름의 사용자 정의함수로 정의해보겠습니다.  

 

import os
import glob
import pandas as pd
import tarfile
import urllib.request

## downloads a zipped tar file (.tar.gz) that contains several CSV files, 
## from a public website. 
def download_and_merge_csv(url: str, down_dir: str, output_csv: str):
    """
    - url: url address from which you want to download a compressed file
    - down_dir: directory to which you want to download a compressed file
    - output_csv: a file name of a exported DataFrame using pd.to_csv() method
    """
    
    # if down_dir does not exists, then create a new directory
    down_dir = 'downloaded_data'
    if os.path.isdir(down_dir):
        pass
    else:
        os.mkdir(down_dir)
        
    # Open for reading with gzip compression.
    # Extract all members from the archive to the current working directory or directory path. 
    with urllib.request.urlopen(url) as res:
        tarfile.open(fileobj=res, mode="r|gz").extractall(down_dir)
    
    # concatenate all extracted csv files
    df = pd.concat(
        [pd.read_csv(csv_file, header=None) 
         for csv_file in glob.glob(os.path.join(down_dir, '*.csv'))])
    
    # export a DataFrame to a csv file
    df.to_csv(output_csv, index=False, header=False)

 

참고로, tarfile.open(fileobj, mode="r") 에서 4개의 mode 를 지원합니다. 

tarfile(mode) 옵션
-. mode="r": 존재하는 데이터 보관소로부터 읽기 (read)
-. mode="a": 존재하는 파일에 데이터를 덧붙이기 (append)
-. mode="w": 존재하는 파일을 덮어쓰기해서 새로운 파일 만들기 (write, create a new file overwriting an existing one)
-. mode="x": 기존 파일이 존재하지 않을 경우에만 새로운 파일을 만들기 (create a new file only if it does not already exist)

* for more information on tarfile module: https://docs.python.org/3/library/tarfile.html

 

 

현재 Jupyter Notebook 커널의 디렉토리에는 아래처럼  아직 다운로드한 파일이 없습니다. 

 

jovyan@kubecon-tutorial-0:~$ pwd
/home/jovyan
jovyan@kubecon-tutorial-0:~$ 
jovyan@kubecon-tutorial-0:~$ ls
data  down_merge_csv.ipynb  kale.log  lost+found
jovyan@kubecon-tutorial-0:~$ 
jovyan@kubecon-tutorial-0:~$

 

 

 

 

이제 위에서 정의한 download_and_merge_csv() 를 사용해서 

  (a) url='https://storage.googleapis.com/ml-pipeline-playground/iris-csv-files.tar.gz' 로 웹사이트로 부터 압축파일을 열고 모든 파일들을 해제해서 

  (b) down_dir='downloaded_data' 의 디렉토리에 다운로드하고, 

  (c) output_csv='iris_merged_data.csv'  라는 이름의 csv 파일로 모든 파일을 합쳐서 내보내기

를 해보겠습니다. 

 

download_and_merge_csv(
    url='https://storage.googleapis.com/ml-pipeline-playground/iris-csv-files.tar.gz', 
    down_dir='downloaded_data', 
    output_csv='iris_merged_data.csv')

 

 

아래의 화면캡쳐처럼 'iris_merged_data.csv' 라는 이름의 csv 파일이 새로 생겼습니다. 그리고 'downloaded_data' 라는 폴더도 새로 생겼습니다. 

 

 

 

 

터미널에서 새로 생긴 'downloaded_data' 로 디렉토리를 이동한 다음에, 파일 리스트를 확인해보니 'iris-1.csv', 'iris-2.csv', 'iris-3.csv' 의 3개 파일이 들어있네요. head 로 상위의 10 개 행을 읽어보니 iris 데이터셋이군요. 

 

jovyan@kubecon-tutorial-0:~$ ls
data  downloaded_data  down_merge_csv.ipynb  iris_merged_data.csv  kale.log  lost+found
jovyan@kubecon-tutorial-0:~$ 
jovyan@kubecon-tutorial-0:~$ 
jovyan@kubecon-tutorial-0:~$ cd downloaded_data/
jovyan@kubecon-tutorial-0:~/downloaded_data$ ls
iris-1.csv  iris-2.csv  iris-3.csv
jovyan@kubecon-tutorial-0:~/downloaded_data$ 
jovyan@kubecon-tutorial-0:~/downloaded_data$ 
jovyan@kubecon-tutorial-0:~/downloaded_data$ head iris-1.csv
5.1,3.5,1.4,0.2,setosa
4.9,3.0,1.4,0.2,setosa
4.7,3.2,1.3,0.2,setosa
4.6,3.1,1.5,0.2,setosa
5.0,3.6,1.4,0.2,setosa
5.4,3.9,1.7,0.4,setosa
4.6,3.4,1.4,0.3,setosa
5.0,3.4,1.5,0.2,setosa
4.4,2.9,1.4,0.2,setosa
4.9,3.1,1.5,0.1,setosa
jovyan@kubecon-tutorial-0:~/downloaded_data$

 

 

 

이번 포스팅이 많은 도움이 되었기를 바랍니다. 

행복한 데이터 과학자 되세요.  :-)

 

반응형
Posted by Rfriend

댓글을 달아 주세요

ZIP 파일 포맷은 일반적으로 자료를 압축하여 보관하는 표준 포맷입니다. 대용량의 데이터를 압축하는 것은 데이터 저장 공간을 적게 사용하고, 데이터 전송에 있어서도 성능 향상을 기대할 수 있으며, 하나의 압축된 파일로 관리할 수 있어 편리합니다.


Python의 zipfile 모듈은 ZIP 파일을 생성하고, 읽기, 쓰기, 추가하기, 압축 파일 해제하기, 압축 파일 리스트와 정보 보기 등을 할 수 있는 클래스를 제공합니다.


이번 포스팅에서는 Python의 zipfile 모듈을 사용해서 (Python 3.x 버전 기준)


(1) 압축 ZIP 파일 쓰기 (write)

(2) 압축 ZIP 파일 읽기 (read)

(3) 압축 ZIP 파일 이름(filename), 자료 리스트(namelist()), 파일 정보(getinfo) 보기

(4) 압축 ZIP 파일 해제하기 (extract)

(5) 웹에서 압축 ZIP 파일 다운로드하여 압축 해제하기 (download and extract)



[ Python zipfile 모듈로 압축 파일 쓰기, 읽기, 해제하기 ]



  (1) 압축 ZIP 파일 쓰기 (write)


먼저, Python으로 (a) 압축 ZIP 파일을 다루는 zipfile 모듈과, (b) 경로(directory, path) 및 폴더/파일을 관리를 할 수 있게 해주는 os 모듈을 importing 하겠습니다.

(cf. Python의 os 모듈을 사용해서 경로 및 폴더/파일 관리하는 방법은 https://rfriend.tistory.com/429 포스팅을 참고하세요.)


다음으로, os 모듈의 chdir() 함수를 사용해서 "Downloads" 폴더로 작업 경로를 변경하겠습니다.

os.getcwd() 로 현재 작업 경로를 확인해보니 "Downloads" 폴더로 작업 경로가 잘 변경되었네요.

os.listdir() 은 현재 작업 경로에 들어있는 파일 리스트를 반환합니다. ['sample_1.txt', 'sample_2.txt', 'sample_3.txt'] 의 3개 텍스트 파일이 예제로 들어있습니다.



import zipfile
import os


## change working directory
base_dir = '/Users/ihongdon/Downloads'
os.chdir(base_dir)

## check the current working directory
os.getcwd()

[Out] '/Users/ihongdon/Downloads'


## show the lists of files in the current working directory
os.listdir()

['sample_2.txt', 'sample_3.txt', 'sample_1.txt']




(1-1) mode='w' : 새로운 압축 파일 쓰기 (단, 기존 압축 파일 있으면 덮어쓰기)


zipfile.ZipFile(file, mode='r') 에서 mode 에는 'w', 'x', 'a', 'r'의 4개 모드가 있고, 기본 설정값은 'r' (읽기) 입니다. 이들 4개 모드별 기능은 아래와 같습니다.


[ zipfile.ZipFile(file, mode) 에서 mode='w'/'x'/'a'/'r' 별 기능 ]

  • mode='w': 새로운 ZIP 압축 파일을 쓰기 (단, 기존 압축 파일이 있으면 덮어쓰기)
                   (to truncate and write a new file)
  • mode='x': 새로운 ZIP 압축 파일을 쓰기 (단, 기존 압축 파일이 있으면 FileExistsError 발생)
                   (to exclusively create and write a new file)
  • mode='a': 기존 ZIP 압축 파일에 자료 추가하기 (to append additional files to an existing ZIP file)
  • mode='r': 기존 ZIP 압축 파일의 자료 읽기 (to read an existing file). 기본 설정 값


myzip_w = zipfile.ZipFile('sample.zip', 'w') 로 'myzip_w'라는 이름의 ZipFile 객체를 새로 만들어 주고, myzip_w.write('sample_1.txt') 함수로 'sample.zip'의 ZIP 파일에 'sample_1.txt' 텍스트 파일을 압축해서 써줍니다.


ZIP 파일을 열고나서 작업 (쓰기, 추가하기, 읽기 등)이 다 끝났으면 시스템이나 프로그램을 종료하기 전에 ZipFile.close() 메소드를 써서 작업 중인 ZIP 파일을 닫아주어야 합니다. 만약 close() 를 하지 않은 상태에서 프로그램을 종료하면 ZIP 파일에 정상적으로 자료가 기록이 되지 않을 것입니다.


ZipFile.is_zipfile(file) 메소드는 ZIP 파일이 존재하면 TRUE를 반환하고, 존재하지 않으면 FALSE를 반환합니다.



## (1) mode='w': to truncate and write a new file
myzip_w = zipfile.ZipFile('sample.zip', 'w')
myzip_w.write('sample_1.txt')

## You must call close() before exiting your program,
## or essential records will not be written.
myzip_w.close()


## ZipFile.is_zipfile(): Return True if a valid ZIP file exists.
zipfile.is_zipfile('sample.zip')

[Out] True




ZipFile 객체는 맥락 관리자(context manager) 이므로 'with 문 (with statement)' 을 지원합니다. 따라서 위의 (1-1) 예제 코드를 아래처럼 with 문을 사용해서 ZIP 파일 쓰기를 할 수도 있습니다.



with zipfile.ZipFile('sample.zip', 'w') as myzip:
    myzip.write('sample_1.txt')
    myzip.close()

 




(1-2) mode='x' : 새로운 압축 파일 쓰기 (단, 기존 파일 있으면 FileExistsError 발생)


위의 mode='w'와는 달리, mode='x'는 새로운 압축 파일을 생성할 때 만약 같은 이름의 ZIP 파일이 존재한다면 'FileExistsError' 가 발생한다는 점이 다릅니다. (to exclusively create and write a new file.)


위의 (1-1)번 예에서 'sample.zip' 이름의 ZIP 파일을 이미 만들었습니다. 여기에 zipfile.ZipFile('sample.zip', mode='x') 로 해서 'sample.zip' 파일 이름으로 ZIP 압축 파일을 만들려고 하면 아래처럼 'FileExistsError: [Errno 17] File exists: 'sample.zip' 의 에러가 발생합니다.



## (2) mode='x': to exclusively create and write a new file.
## if file refers to an existing file, a 'FileExistsError' will be raised.
myzip_x = zipfile.ZipFile('sample.zip', 'x')

[Out]
--------------------------------------------------------------------------- FileExistsError Traceback (most recent call last) <ipython-input-7-bd84b411165c> in <module> 1 ## (2) mode='x': to exclusively create and write a new file. 2 ## if file refers to an existing file, a 'FileExistsError' will be raised. ----> 3 myzip_x = zipfile.ZipFile('sample.zip', 'x') ~/opt/anaconda3/lib/python3.8/zipfile.py in __init__(self, file, mode, compression, allowZip64, compresslevel, strict_timestamps) 1249 while True: 1250 try: -> 1251 self.fp = io.open(file, filemode) 1252 except OSError: 1253 if filemode in modeDict: FileExistsError: [Errno 17] File exists: 'sample.zip'

 



위의 'FileExistsError'가 발생했다면, 아래처럼 ZIP 파일 이름을 기존에는 없는 파일 이름으로 바꾸어서 zipfile.ZipFile(new_file_name, mode='x') 로 해서 압축 파일을 생성할 수 있습니다.

(mode='w' 로 하면 기존 파일을 덮어쓰기 하므로 주의가 필요합니다.)


ZipFile.namelist() 는 ZipFile 객체에 압축되어 있는 자료(archives)의 이름 리스트를 출력해줍니다.



myzip_x = zipfile.ZipFile('sample2.zip', 'x')
myzip_x.write('sample_2.txt')
myzip_x.close()

myzip_x.namelist()

[Out] ['sample_2.txt']





(1-3) mode='a' : 기존 ZIP 압축 파일에 자료 추가 (to append, add up)


만약 기존에 존재하는 ZIP 파일에 새로운 자료를 추가(append)하고 싶다면 mode='a' 로 설정해주면 됩니다.


아래 예제에서는 위의 (1-1)에서 'sample_1.txt'의 텍스트 파일을 'sample.zip' 이름으로 압축해서 이미 만들어두었던 ZIP 파일에 더하여, 'sample_2.txt', 'sample_3.txt' 의 텍스트 파일까지 추가하여 'sample.zip' 이름의 ZIP 파일에 압축해보겠습니다.



## (3) mode='a': to append to an existing file.
myzip_a = zipfile.ZipFile('sample.zip', 'a')
myzip_a.write('sample_2.txt')
myzip_a.write('sample_3.txt')
myzip_a.close()

myzip_a.namelist()

[Out] ['sample_1.txt', 'sample_2.txt', 'sample_3.txt']





(1-4) 여러개의 자료를 하나의 압축 ZIP 파일에 쓰기 (for loop, ZipFile(), write())


하나의 ZIP 압축 파일에 여러개의 자료를 압축해서 쓰고 싶을 때는 for loop 반복문을 같이 사용해주면 됩니다. (mode 는 필요와 상황에 맞게 'w', 'x', 'a' 중에서 선택)


아래 예제는 'myzip_all' 이름의 ZipFile 객체로 'sample_all.zip' 의 ZIP 파일에 ['sample_1.txt', 'sample_2.txt', 'sample_3.txt'] 의 3개 텍스트 파일들을 for loop 반복문을 사용해서 하나씩 차례대로 호출해서 myzip_all.write(f) 로 'sample_all.zip' 파일에 써주었습니다.



## (4) writing files to a zip file: with statement & for loop
file_list = ['sample_1.txt', 'sample_2.txt', 'sample_3.txt']

with zipfile.ZipFile('sample_all.zip', 'w') as myzip_all:
    for f in file_list:
        myzip_all.write(f)
        print(f, 'is written to myzip_all.zip')
    myzip_all.close()


[Out]
sample_1.txt is written to myzip_all.zip sample_2.txt is written to myzip_all.zip sample_3.txt is written to myzip_all.zip


myzip_all.namelist()

[Out] ['sample_1.txt', 'sample_2.txt', 'sample_3.txt']





(1-5) zipfile.ZipFile(file, mode='r',

           compression=ZIP_STORED, allowZip64=True, compresslevel=None)


매개변수

설명

 compression

 compression은 자료를 압축 파일에 쓰기 위한 ZIP 압축 메소드이며, 기본 설정값은 ZIP_STORED 입니다.


Python 버전 3.1 부터 아래의 파일과 같은 객체를 지원합니다.

  • zipfile.ZIP_STORED  (* default)
  • zipfile.ZIP_DEFLATED
  • zipfile.ZIP_BZIP2

Python 버전 3.3 부터는 ZIP_LZMA 객체를 지원합니다.

  • zipfile.ZIP_LZMA

 allowZip64

 allowZip64=True (기본 설정) 이면 ZIP 파일 크기가 4GB를 넘을 경우 ZIP64 extensions 를 사용해서 ZIP 파일을 생성합니다.

 

 만약 allowZip64=False 설정인데 ZIP 파일 크기가 4GB를 넘을 경우에는 exception error 가 발생합니다.

 compresslevel

 compresslevel 매개변수는 자료를 압축할 수준을 지정할 때 사용합니다.

(compression 이 ZIP_STORED, ZIP_LZMA 일 경우에는 효과가 없으며, ZIP_DEPLATED, ZIP_BZIP2 에만 설정 가능합니다.)

  • compression=ZIP_DEFLATED 일 경우 compresslevel=0~9 까지 설정 가능
  • compression=ZIP_BZIP2 일 경우 compresslevel=1~9 까지 설정 가능




  (2) 압축 ZIP 파일 읽기 (read)


ZIP 압축 파일에 들어있는 자료를 읽으려면 zipfile.ZipFile(file, mode='r') 로 해서 ZipFile 객체를 '읽기 모드'로 생성한 후, ZipFile.read() 메소드로 ZIP 파일 내 압축되어 있는 자료를 읽을 수 있습니다.

아래 예제는 위의 (1-1)에서 만들었던 'sample.zip'의 ZIP 파일 안에 압축되어 있는 'sample_1.txt' 텍스트 자료를 읽어본 것입니다. 압축을 해제하지 않고도 ZIP 압축 파일 내의 특정 자료를 선택해서 그 자료만 읽을 수 있어서 편리합니다.


## sample.zip
myzip_w.namelist()

[Out] ['sample_1.txt']


## mode='r': to read an existing file
myzip_r = zipfile.ZipFile('sample.zip', 'r')
print(myzip_r.read('sample_1.txt'))

[Out] b'x1,x2,x3\n1,2,3\n4,5,6\n7,8,9\n'


# ## or equivalently above
# with myzip_r.open('sample_1.txt') as s1:
#     print(s1.read())




위의 압축 파일 내 자료를 읽은 결과가 눈에 잘 안들어 올 수도 있는데요, 아래에는 참고로 pandas 의 read_csv() 메소드를 사용해서 'sample_1.txt' 파일을 출력해본 것입니다.


import pandas as pd

sample_1_df = pd.read_csv('sample_1.txt')
print(sample_1_df)

[Out]
x1 x2 x3 0 1 2 3 1 4 5 6 2 7 8 9





  (3) 압축 ZIP 파일 이름(filename), 자료 리스트(namelist()), 파일 정보(getinfo) 보기


(3-1) ZipFile.is_zipfile(file) : Zip 파일이 존재하면 True, 존재하지 않으면 False



file_list = ['sample_1.txt', 'sample_2.txt', 'sample_3.txt']

with zipfile.ZipFile('sample_all.zip', 'w') as myzip_all:
    for f in file_list:
        myzip_all.write(f)
    myzip_all.close()


## ZipFile.is_zipfile(): Return True if a valid ZIP file exists.
zipfile.is_zipfile('sample_all.zip')

[Out] True

 



(3-2) ZipFile.filename : ZIP 압축 파일 이름 출력



## ZipFile.filename: Name of the ZIP file
myzip_all.filename

[Out] 'sample_all.zip'




(3-3) ZipFile.namelist() : ZIP 압축 파일 내 자료 이름 리스트 출력



## file name lists of sample_all.zip
myzip_all.namelist()

[Out] ['sample_1.txt', 'sample_2.txt', 'sample_3.txt']




(3-4) ZipFile.getinfo(member) : ZIP 파일 내 자료(member)의 정보 출력


파일 이름 (file name), 파일 모드 (file mode), 파일 크기 (file size)



## ZipFile.getinfo(): Zip information about the archive member name.
myzip_all.getinfo('sample_1.txt')

[Out] <ZipInfo filename='sample_1.txt' filemode='-rw-r--r--' file_size=27>




  (4) 압축 ZIP 파일 해제하기 (extract)


(4-1) ZipFile.extract(file, path) : ZIP 파일 내 1개의 자료만 압축 해제하기


이때 압축을 해제한 자료를 저장할 경로(path)를 별도로 지정해 줄 수 있습니다. (path 를 지정하지 않으면 현재 작업경로에 압축 해제함)



## (4-1) ZipFile.extract()
## : extracting a member from the archive to the current working directory.
extract_path = '/Users/ihongdon/Downloads/sample_3'
zipfile.ZipFile('sample_all.zip').extract('sample_3.txt', path=extract_path)

[Out] '/Users/ihongdon/Downloads/sample_3/sample_3.txt'

 



위의 (4-1)에서는 압축 해제한 1개 파일을 저장할 경로(path)를 지정해주었는데요, 해당 경로에 os.listdir(extract_path) 로 확인해 보니 원하는 'sample_3.txt' 텍스트 자료가 잘 압축 해제되어 저장되어 있네요.



os.listdir(extract_path)

[Out] ['sample_3.txt']

 



(4-2) ZipFile.extractall() : ZIP 파일 내 모든 자료를 압축 해제



## (4-2) ZipFile.extractall()
## : extracting all members from the archive to the current working directory.
extractall_path = '/Users/ihongdon/Downloads/sample_all'
zipfile.ZipFile('sample_all.zip').extractall(extractall_path)


os.listdir(extractall_path)

[Out] ['sample_2.txt', 'sample_3.txt', 'sample_1.txt']





  (5) 웹에서 ZIP 파일 다운로드하여 압축 해제하기 (download and extract ZIP file)


아래 예제는 웹사이트에서 영화 추천에 사용되는 영화 평가 점수(movie ratings)를 모아놓은  데이터셋('movielens.csv', etc.)ZIP 포맷으로 압축해 놓은 'ml-latest-small.zip' 파일을 Keras의 메소드를 사용해 다운로드 한 다음에, zipfile 모듈의 ZipFile.extractall() 메소드로 전체 자료를 압축 해제한 것입니다.



## Download the movielens data from website url
import tensorflow.keras as keras
from zipfile import ZipFile
from pathlib import Path

import os


movielens_data_file_url = (
    "http://files.grouplens.org/datasets/movielens/ml-latest-small.zip"
)

movielens_zipped_file = keras.utils.get_file(
    "ml-latest-small.zip", movielens_data_file_url, extract=False
)

keras_datasets_path = Path(movielens_zipped_file).parents[0]
movielens_dir = keras_datasets_path / "ml-latest-small"

## Only extract the data the first time the script is run.
if not movielens_dir.exists():
    with ZipFile(movielens_zipped_file, "r") as zip:
        zip.extractall(path=keras_datasets_path) # extract all members in a ZIP file

 



사용자 별 영화 평가점수('ratings.csv')와 영화 정보('movies.csv') 데이터셋을 사용해서 영화 추천 (movie recommentation) 에 사용할 수 있습니다.



print('datasets path:', keras_datasets_path)

[Out] datasets path: /Users/ihongdon/.keras/datasets


print(os.listdir(keras_datasets_path))

[Out] ['cowper.txt', 'reuters_word_index.json', 'imdb_word_index.json', 'flower_photos.tar.gz', 'cifar-10-batches-py', 'mnist.npz', 'ml-latest-small.zip', 'ml-latest-small', 'fashion-mnist', 'butler.txt', 'imdb.npz', 'cifar-10-batches-py.tar.gz', 'boston_housing.npz', 'creditcard.csv', 'creditcard.zip', 'derby.txt', 'train.csv', 'flower_photos', 'reuters.npz', 'fsns.tfrec']

os.listdir(movielens_dir)

[Out] ['links.csv', 'tags.csv', 'ratings.csv', 'README.txt', 'movies.csv']



[Reference]

* zipfile -Work with ZIP archives: https://docs.python.org/3/library/zipfile.html


이번 포스팅이 많은 도움이 되었기를 바랍니다.

행복한 데이터 과학자 되세요! :-)



반응형
Posted by Rfriend

댓글을 달아 주세요

이번 포스팅에서는 (1) 파이썬의 자료형 중에서도 사전형(Dictionary)을 키와 값 (Key and Value) 의 쌍으로 인쇄를 할 때 좀더 가독성을 좋게 하도록 키(Key) 에서 일정 간격을 띄우고 나서 값(Value)을 인쇄하는 옵션을 소개하겠습니다.  


그리고 소소한 팁으로 (2) 파이썬 인쇄 escape 옵션, (3) 파이썬 인쇄 sep, end 옵션을 추가로 소개하겠습니다. 



  (1) 파이썬 사전형의 키와 값을 일정 간격을 두고 인쇄하기

      (Print Key, Value of Python Dictionary with fixed space)




먼저, 예제로 사용할 간단한 파이썬 사전형(Dictionary) 객체를 키와 값의 쌍(pair of key and value)으로 만들어보고 print() 로 인쇄를 해보겠습니다


사전형 객체에 대해서 그냥 print() 로 인쇄를 하면 옆으로 길게 쭈욱~ 늘어서 인쇄가 되기 때문에 아무래도 한눈에 보기가 쉽지 않습니다. 



my_dict = {'first name': 'KilDong.', 

           'last name': 'Hong.',

           'age': '30.', 

           'address': 'Seoul, Korea.'}



print(my_dict)

[Out]

{'first name': 'KilDong.', 'last name': 'Hong.', 'age': '30.', 'address': 'Seoul, Korea.'}





그러면, 좀더 보기에 좋도록 이번에는 dictionary.items() 로 키와 값을 분해해서 각각 가져오고, for loop 순환문으로 반복을 하면서 각 키와 값을 한줄에 하나씩 인쇄를 해보겠습니다. 이때 format() 메소드를 사용해서 Key, Value 값을 인쇄할 때 각각 치환해주었습니다. 

바로 앞의 예에서 그냥 print() 한 것보다는 한결 보기에 좋습니다만, Key 문자열의 길이가 들쭉날쭉 하다보니 Key : Value 로 쌍을 이루어서 인쇄를 할 때 Value 인쇄가 시작하는 위치도 역시 들쭉날쭉해서 좀 정신이 없고 눈에 잘 안들어오는 한계가 있습니다. 



for k, v in my_dict.items():

    print("{} : {}".format(k, v))


[Out]
first name : KilDong.
last name : Hong.
age : 30.
address : Seoul, Korea.





이럴 때 {!r:15s} 으로 특정 숫자만큼의 string 간격을 두고 인쇄하라는 옵션을 추가해주면 아래와 같이 Key 문자열의 시작위치부터 15 string 만큼 각격을 두고, 이어서 다음의 문자열(여기서는 ': {value}')을 인쇄하게 됩니다. 위의 예보다는 아래의 예가 한결 Key : Value 쌍을 한눈에 보기에 좋아졌습니다.   



for k, v in my_dict.items():

    print("{!r:15s} : {}".format(k, v))


[Out]

'first name' : KilDong. 'last name' : Hong. 'age' : 30. 'address' : Seoul, Korea.

 





  (2) 파이썬 인쇄 escape 옵션 (Python Print escape options)

파이썬 문법을 탈출(escape)하여 인쇄할 수 있는 소소한 옵션들이 몇 개 있습니다. 

(아래에서 \ 는 역슬래쉬  , back-slash 입니다)


  • \n : 새로운 줄로 바꾸어서 인쇄하기
  • \t : 탭(tab)으로 들여쓰기해서 인쇄하기 (오른쪽으로 탭한 만큼 밀어서 인쇄)
  • \b : 뒤에서 한칸 back-space 하여 인쇄하기 (제일 뒤에 문자가 있으면 삭제되어서 인쇄)
  • \" : 큰 따옴표(") 인쇄하기
  • \' : 작은 따옴표(') 인쇄하기
  • \\ : 역슬래쉬('\') 인쇄하기


  • \n : 새로운 줄로 바꾸어서 인쇄하기


for k, v in my_dict.items():

    print("\n{} : {}".format(k, v))


[Out]

first name : KilDong.

last name : Hong.

age : 30.

address : Seoul, Korea.





  • \t : 탭(tab)으로 들여쓰기해서 인쇄하기 (오른쪽으로 탭한 만큼 밀어서 인쇄)


for k, v in my_dict.items():

    print("\t{} : {}".format(k, v))


[Out]
	first name : KilDong.
	last name : Hong.
	age : 30.
	address : Seoul, Korea.





  • \b : 뒤에서 한칸 back-space 하여 인쇄하기 (제일 뒤에 문자가 있으면 삭제되어서 인쇄)



for k, v in my_dict.items():

    print("{} : {}\b".format(k, v))


[Out]
first name : KilDong
last name : Hong
age : 30
address : Seoul, Korea

 




  • \" : 큰 따옴표(") 인쇄하기


for k, v in my_dict.items():

    print("{} : \"{}\"".format(k, v))


[Out]
first name : "KilDong."
last name : "Hong."
age : "30."
address : "Seoul, Korea."

 




  • \\ : 역슬래쉬('\') 인쇄하기


for k, v in my_dict.items():

    print("{} : \\{}\\".format(k, v))


[Out]
first name : \KilDong.\
last name : \Hong.\
age : \30.\
address : \Seoul, Korea.\

 





  (3) 파이썬 인쇄 sep, end 옵션 (Python Print sep, end options)


  • sep="separator" 옵션 : 두 개의 문자열 사이에 구분자(separator) 문자로 구분하여 붙여서 인쇄
  • end="end_string" 옵션 : 앞의 문자열에 바로 이어서 end_string을 붙여서 인쇄


앞의 (1)번에서 예로 들었던 Key : Value 쌍으로 item 한줄씩 인쇄하는 것을 sep, end 옵션을 사용해서 똑같이 재현해보겠습니다. 


  • sep="separator" 옵션 : 두 개의 문자열 사이에 구분자(separator) 문자로 구분하여 붙여서 인쇄


for k, v in my_dict.items():

    print(k, v, sep=" : ")


[Out]

first name : KilDong. last name : Hong. age : 30. address : Seoul, Korea.

 




  • end="end_string" 옵션 : 앞의 문자열에 바로 이어서 end_string을 붙여서 인쇄


for k, v in my_dict.items():

    print(k + " : ", end=v+"\n")


[Out]
first name : KilDong.
last name : Hong.
age : 30. 

address : Seoul, Korea.




많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. 



반응형
Posted by Rfriend

댓글을 달아 주세요

Python은 고수준의 객체지향 프로그래밍 언어입니다. 파이썬 툴을 사용해 재사용 가능한 코드를 작성하는 기능은 파이썬이 가지고 있는 큰 장점 중의 하나입니다. 


Python Functools 는 고차함수(high order functions)를 위해 설계된 라이브러리로서, 호출 가능한 기존의 객체, 함수를 사용하여 다른 함수를 반환하거나 활용할 수 있게 해줍니다. Functools 라이브러리는 기존 함수를 이용하는 함수를 모아놓은 모듈이라고 하겠습니다. Functools 라이브러리에는 partial(), total_ordering(), reduce(), chched_perperty() 등 여러 함수가 있는데요, 이번 포스팅에서는 partial() 메소드에 대해서 소개하겠습니다. 

(* functools.reduce() 함수 참고 : https://rfriend.tistory.com/366)





Functools partial 함수는 기존 파이썬 함수를 재사용하여 일부 위치 매개변수 또는 키워드 매개변수를 고정한(freezed, fixec) 상태에서, 원래의 함수처럼 작동하는 새로운 부분 객체(partial object)를 반환합니다. functools.partial() 함수의 syntax는 아래와 같이, 기존 함수이름을 써주고, 고정할 매개변수 값을 써주면 됩니다.  


from functools import partial


functools.partial(func, /, *args, **keywords)


간단한 예제로서, 숫자나 문자열을 정수(integer)로 변환해주는 파이썬 내장 함수 int(x, base=10)를 재활용하여, base=2 로 고정한 새로운 함수를 functools.partial() 함수로 만들어보겠습니다. 



# python build-in function int(x, base=10)

int('101', base=2)

[Out]: 5

int('101', base=5)

[Out]: 26

 



# create a basetwo() function using functools.partial() and int() function

from functools import partial


basetwo = partial(int, base=2)  # freeze base=2

basetwo('101')

[Out]: 5




int() 함수를 재활용해서 base=2 로 고정해서 새로 만든 basetwo() 라는 이름의 함수에 basetwo.__doc__ 로 설명을 추가하고, 호출해서 확인해보겠습니다. 



# add __doc__ attribute

basetwo.__doc__ = 'Convert base 2 string to an int.'


basetwo.__doc__

[Out]: 'Convert base 2 string to an int.'




functools.partial() 로 만든 새로운 객체는 func, args, keywords 속성(attributes)을 가지고 있습니다. 

이번 예에서는 재활용한 기존 함수(func)가 int(), 키워드 매개변수(keywords)가 base=2 ({'base': 2} 였는데요, 아래처럼 확인할 수 있습니다. 



basetwo.func

[Out]: int


basetwo.args

[Out]: ()


basetwo.keywords

[Out]: {'base': 2}

 



* functools library refreence: https://docs.python.org/3/library/functools.html#module-functools


많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)



반응형
Posted by Rfriend

댓글을 달아 주세요

파이썬 객체를 일정한 규칙(규약)을 따라서 (a) 효율적으로 저장하거나 스트림으로 전송할 때 파이썬 객체의 데이터를 줄로 세워 저장하는 것을 직렬화(serialization) 라고 하고, (b) 이렇게 직렬화된 파일이나 바이트를 원래의 객체로 복원하는 것을 역직렬화(de-serialization)라고 합니다. 


직렬화, 역직렬화를 하는데 Pickle, JSON, YAML 등 여러가지 방법이 있습니다. Pickle 방식은 사람이 읽을 수 없는 반면 저장이나 전송이 효율적입니다. 대신 JSON, YAML 방식은 저장이나 전송이 Pickle 보다는 덜 효율적이지만 사람이 읽을 수 있는 가독성이 좋은 장점이 있습니다. (* 파이썬에서 JSON 데이터 읽고 쓰기: https://rfriend.tistory.com/474)


이번 포스팅에서는 Pickle 방식으로 이진 파일이나 바이트 객체로 직렬화하고, 이를 다시 역직렬화해서 불러오는 방법에 대해서 소개하겠습니다. Pickle 방식에서는 직렬화(serialization)는 Pickling 이라고도 하며, 역직렬화(deserialization)는 Unpickling 이라고도 합니다. 


파이썬에서 Pickle 방식으로 직렬화, 역직렬화하는데는 파이썬으로 작성되고 파이썬 표준 라이브러리에 포함되어 있는 pickle module, C로 작성되어 매우 빠르지만 Subclass 는 지원하지 않는 cPickle module 의 두 가지 패키지를 사용할 수 있습니다. (* source : https://pymotw.com/2/pickle/)


파이썬의 Pickle 방식으로 직렬화할 수 있는 객체는 모든 파이썬 객체를 망라합니다. (정수, 실수, 복소소, 문자열, 블리언, 바이트 객체, 바이트 배열, None, 리스트, 튜플, 사전, 집합, 함수, 클래스, 인스턴스 등)


이번 포스팅에서는 Python 3.7 버전(protocol = 3)에서 pickle 모듈을 사용하여 


(1-1) 파이썬 객체를 직렬화하여 이진 파일(binary file)에 저장하기 : pickle.dump()

(1-2) 직렬화되어 있는 이진 파일로 부터 파이썬 객체로 역직렬화하기: pickle.load()


(2-1) 파이썬 객체를 직렬화하여 메모리에 저장하기: pickle.dumps()

(2-2) 직렬화되어 있는 바이트 객체(bytes object)를 파이썬 객체로 역직렬화: pickle.loads()


로 나누어서 각 방법을 소개하겠습니다. 


pickle.dump()와 pickle.dumps() 메소드, 그리고 pickle.load()와 pickle.loads() 메소드의 끝에 's'가 안붙고 붙고의 차이를 유심히 봐주세요. 


 구분

 Binary File on disk

Bytes object on memory 

 직렬화

(serialization)

 with open("file.txt", "wb") as MyFile:

     pickle.dump(MyObject, MyFile)

 pickle.dumps(MyObject, MyBytes)

 역직렬화

(deserialization)

 with open("file.txt", "rb") as MyFile:

     MyObj2 = pickle.load(MyFile)

 MyObj2 = pickle.loads(MyBytes)




직렬화, 역직렬화를 할 때 일정한 규칙을 따라야 하는데요, 파이썬 버전별로 Pickle Protocol Version 은 아래에 정리한 표를 참고하시기 바랍니다. 그리고 상위 버전의 Pickle Protocol Version에서 저장한 경우 하위 버전에서 역직렬화할 수 없으므로 주의가 필요합니다. (가령 Python 3.x에서 Protocol = 3 으로 직렬화해서 저장한 파일을 Python 2.x 에서 Protocol = 2 버전으로는 역직렬화 할 수 없습니다.)




먼저, 예제로 사용할 정수, 텍스트, 실수, 블리언 고유 자료형을 포함하는 파이썬 사전 객체 (python dictionary object)를 만들어보겠습니다. 



MyObject = {'id': [1, 2, 3, 4], 

           'name': ['KIM', 'CHOI', 'LEE', 'PARK'], 

           'score': [90.5, 85.7, 98.9, 62.4], 

           'pass_yn': [True, True, True, False]}





 (1-1) 파이썬 객체를 직렬화하여 이진 파일(binary file)에 저장하기 : pickle.dump()



import pickle


with open("serialized_file.txt", "wb") as MyFile:

    pickle.dump(MyObject, MyFile, protocol=3)



with open("serialized_file.txt", "wb") as MyFile 함수를 사용해서 "serialized_file.txt" 라는 이름의 파일을 이진 파일 쓰기 모드 ("wb") 로 열어 놓습니다. (참고로, with open() 은 close() 를 해줄 필요가 없습니다.)


pickle.dump(MyObject, MyFile) 로 위에서 만든 MyObject 사전 객체를 MyFile ("serialized_file.txt") 에 직렬화해서 저장합니다. 


Python 3.7 버전에서 작업하고 있으므로 protocol=3 으로 지정해줬는데요, Python 3.0~3.7 버전에서는 기본값이 protocol=3 이므로 안써줘도 괜찮습니다. 


현재의 작업 폴더에 가보면 "serialized_file.txt" 파일이 생성이 되어있을 텐데요, 이 파일을 클릭해서 열어보면 아래와 같이 사람이 읽을 수 없는 binary 형태로 저장이 되어 있습니다. (만약 사람이 읽을 수 있고 가독성이 좋은 저장, 전송을 원한다면 JSON, YAML 등을 사용해서 직렬화 하면됨)





 (1-2) 직렬화되어 있는 이진 파일로 부터 파이썬 객체로 역직렬화: pickle.load()



import pickle


with open("serialized_file.txt", "rb") as MyFile:

    UnpickledObject = pickle.load(MyFile)



UnpickledObject

[Out]:
{'id': [1, 2, 3, 4],
 'name': ['KIM', 'CHOI', 'LEE', 'PARK'],
 'score': [90.5, 85.7, 98.9, 62.4],
 'pass_yn': [True, True, True, False]}


with open("serialized_file.txt", "rb") as MyFile 를 사용하여 위의 (1-1)에서 파이썬 사전 객체를 직렬화하여 이진 파일로 저장했던 "serialized_file.txt" 파일을 이진 파일 읽기 모드 ("rb") 로 MyFile 이름으로 열어 놓습니다. 


UnpickledObject = pickle.load(MyFile) 로 앞에서 열어놓은 MyFile 직렬화된 파일을 역직렬화(de-serialization, unpickling, decoding) 하여 UnpickledObject 라는 이름의 파이썬 객체를 생성합니다. 


이렇게 만든 UnpickledObject 파이썬 객체를 호출해보니 다시 사람이 읽을 수 있는 사전 객체로 다시 잘 복원되었음을 알 수 있습니다. 




 (2-1) 파이썬 객체를 직렬화하여 메모리에 Bytes object로 저장하기pickle.dumps()



import pickle 


MyBytes = pickle.dumps(MyObject, protocol=3)



# unreadable bytes object

MyBytes

[Out]:

b'\x80\x03}q\x00(X\x02\x00\x00\x00idq\x01]q\x02(K\x01K\x02K\x03K\x04eX\x04\x00\x00\x00nameq\x03]q\x04(X\x03\x00\x00\x00KIMq\x05X\x04\x00\x00\x00CHOIq\x06X\x03\x00\x00\x00LEEq\x07X\x04\x00\x00\x00PARKq\x08eX\x05\x00\x00\x00scoreq\t]q\n(G@V\xa0\x00\x00\x00\x00\x00G@Ul\xcc\xcc\xcc\xcc\xcdG@X\xb9\x99\x99\x99\x99\x9aG@O333333eX\x07\x00\x00\x00pass_ynq\x0b]q\x0c(\x88\x88\x88\x89eu.'



위의 (1-1)이 파이썬 객체를 이진 파일(binary file) 로 로컬 디스크에 저장하였다면, 이번 (2-1)은 pickle.dumps(object_name, protocol=3) 을 사용해서 메모리에 Bytes object로 직렬화해서 저장하는 방법입니다. pickle.dumps() 메소드의 제일 뒤에 's'가 추가로 붙어있는 것 유의하세요. 


이렇게 직렬화해서 저장한 Bytes object의 경우 사람이 읽을 수 없는 형태입니다. (반면, 컴퓨터한테는 데이터를 저장하기에 더 효율적인 형태)




 (2-2) 직렬화되어 있는 바이트 객체를 파이썬 객체로 역직렬화: pickle.loads()



import pickle


MyObj2 = pickle.loads(MyBytes)


MyObj2

[Out]:
{'id': [1, 2, 3, 4],
 'name': ['KIM', 'CHOI', 'LEE', 'PARK'],
 'score': [90.5, 85.7, 98.9, 62.4],
 'pass_yn': [True, True, True, False]}

 


위의 (2-1)에서 직렬화하여 저장한 바이트 객체 MyBytes 를 pickle.loads() 메소드를 사용하여 역직렬화하여 MyObj2 라는 이름의 파이썬 객체를 생성한 예입니다.  


* reference: https://docs.python.org/3.7/library/pickle.html

* pickle and cPicklehttps://pymotw.com/2/pickle/


많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)



반응형
Posted by Rfriend

댓글을 달아 주세요

지난번 포스팅에서는 파일을 열고(open), 파일을 읽고(read), 쓰고(write), 닫기(close)를 하는 방법을 소개하였습니다.  

 

이번 포스팅에서는 Python 에서 

 

(1) 문자열로 이루어진 리스트를 텍스트 파일에 쓰기

    - (1-1) 한 줄씩 쓰기 : write() 메소드 (for loop 문과 함께 사용)

    - (1-2) 한꺼번에 모든 줄 쓰기 : writelines() 메소드

 

(2) 텍스트 파일을 읽어오기

    - (2-1) 텍스트를 한 줄씩 읽어오기 : readline() 메소드 (while 문과 함께 사용)

    - (2-2) 텍스트를 한꺼번에 모두 읽어오기 : readlines() 메소드

 

에 대해서 소개하겠습니다. 

 

 

 (1-1) 문자열로 이루어진 리스트를 한 줄씩 텍스트 파일에 쓰기 : write() 메소드

 

 

 

예제로 사용할 텍스트는 영화 매트릭스(movie Matrix)에서 모피어스가 네오에게 말했던 대사 (Morpheus Quotes to Neo) 중 몇 개로 이루어진 파이썬 리스트입니다. '\n'으로 줄을 구분하였습니다. 

 

 

matrix_quotes = ["The Matrix is the world that has been pulled over your eyes to blind you from the truth.\n", 

                 "You have to let it all go, Neo. Fear, doubt, and disblief. Free your mind.\n", 

                 "There is a difference between knowing the path and walking the path.\n", 

                 "Welcom to the desert of the real!\n"]

 

 

* image source: https://www.elitecolumn.com/morpheus-the-matrix-quotes/morpheus-the-matrix-quotes-4/

 

위의 텍스트 문자열로 이루어진 'matrix_quotes' 리스트를 'matrix_quotes.txt'라는 이름의 파일에 한 줄씩 써보도록 하겠습니다. 먼저 with open('matrix_quotes.txt', 'w') 함수를 사용해서 'matrix_quotes.txt'라는 이름의 파일을 '쓰기 모드('w')'로 열고, 모두 4줄로 이루어진 리스트이므로 for loop 순환문을 이용해서 한줄 씩 line 객체로 가져온 다음에 f.write(line) 메소드로 한 줄씩(line by line) 'matrix_quotes.txt' 텍스트 파일에 써보겠습니다. 

 

 

with open('matrix_quotes.txt', 'w') as f:

    for line in matrix_quotes:

        f.write(line)

 

 

* 참고로, with open() 함수를 사용하면 close() 를 해주지 않아도 알아서 자동으로 close()를 해줍니다. 

* with open('matrix_quotes.txt', 'w') 에서 'w' 는 쓰기 모드를 의미합니다. 

 

 

현재 Jupyter notebook을 열어서 작업하고 있는 폴더에 'matrix_quotes.txt' 텍스트 파일이 생성되었음을 확인할 수 있습니다. 

 

 

 

 

for loop 문과 write() 메소드를 사용해서 텍스트를 파일에 쓴 'matrix_quotes.txt' 파일을 더블 클릭해서 열어보니 Python list 의 내용과 동일하고, 줄 구분도 '\n'에 맞게 잘 써진 것을 알 수 있습니다. 

 

 

 

 

 

 (1-2) 문자열로 이루어진 리스트의 모든 줄을 텍스트 파일에 쓰기: writelines() 메소드 

 

그런데 위의 write() 메소드의 경우 여러 개의 줄이 있을 경우 for loop 반복 순환문을 함께 써줘야 하는 불편함이 있습니다. 이때 writelines() 메소드를 사용하면 리스트 안의 모든 줄을 한꺼번에 텍스트 파일에 써줄 수 있어서 편리합니다.  위의 (1-1)과 동일한 작업을 writelines() 메소드를 사용해서 하면 아래와 같습니다. 

 

 

matrix_quotes = ["The Matrix is the world that has been pulled over your eyes to blind you from the truth.\n", 

                 "You have to let it all go, Neo. Fear, doubt, and disblief. Free your mind.\n", 

                 "There is a difference between knowing the path and walking the path.\n", 

                 "Welcom to the desert of the real!\n"]

 

 

with open('maxtix_quotes_2.txt', 'w') as f:

    f.writelines(matrix_quotes)

 

 

 

Jupyter notebook을 작업하고 있는 폴더에 가서 보니 'matrix_quotes_2.txt' 파일이 새로 잘 생성되었습니다. 

 

 

 

 

 

  (2-1) 텍스트 파일을 한 줄씩 읽어오기 : readline() 메소드

 

이제는 방금전 (1-1)에서 만든 'matrix_quotes.txt' 텍스트 파일로 부터 텍스트를 한 줄씩 읽어와서 matrix_quotes_list 라는 이름의 파이썬 리스트를 만들어보겠습니다. 

 

 

 

readline() 메소드는 텍스트 파일을 '\n', '\r', '\r\n' 과 같은 개행 문자(newline) 를 기준으로 한 줄씩 읽어오는 반면에 vs. readlines() 메소드는 텍스트 파일 안의 모든 텍스트를 한꺼번에 읽어오는 차이가 있습니다.  따라서 한 줄씩만 읽어오는 readline() 메소드를 사용해서 텍스트 파일 내 모든 줄을 읽어오려면 while 순환문을 같이 사용해주면 됩니다. 

 

 

with open('matrix_quotes.txt', 'r') as text_file:    matrix_quotes_list = []    line = text_file.readline()        while line != '':        matrix_quotes_list.append(line)        line = text_file.readline()

 

 

 

matrix_quotes_list

[Out]: 
['The Matrix is the world that has been pulled over your eyes to blind you from the truth.\n',  'You have to let it all go, Neo. Fear, doubt, and disblief. Free your mind.\n',  'There is a difference between knowing the path and walking the path.\n',  'Welcom to the desert of the real!\n',  '']

 

 

* 참고로 with open('matrix_quotes.txt', 'r') 에서 'r'은 '읽기 모드'를 의미합니다. 

 

 

만약 파일을 한 줄씩 읽어오면서 매 10번째 행마다 새로운 파일에 쓰기를 하고 싶다면 아래 코드 참고하세요. 

with open(in_name, 'r') as in_file:
    with open(out_name, 'w') as out_file:
        count = 0
        for line in in_file:
            if count % 10 == 0:
                out_file.write(line)
            count += 1

 

 

 

  (2-2) 텍스트 파일을 모두 한꺼번에 읽어오기 : readlines() 메소드

 

이번에는 readlines() 메소드를 사용해서 'matrix_quotes.txt' 텍스트 파일 안의 모든 줄을 한꺼번에 읽어와서 matrix_quotes_list_2 라는 이름의 파이썬 리스트를 만들어보겠습니다.  readlines() 메소드는 한꺼번에 텍스트를 읽어오기 때문의 위의 (2-1) 의 readline()메소드와 while 순환문을 함께 쓴 것도다 코드가 간결합니다. 

 

 

with open('matrix_quotes.txt', 'r') as text_file:

    matrix_quotes_list_2 = text_file.readlines()

 

 

matrix_quotes_list_2

[Out]: 
['The Matrix is the world that has been pulled over your eyes to blind you from the truth.\n',  'You have to let it all go, Neo. Fear, doubt, and disblief. Free your mind.\n',  'There is a difference between knowing the path and walking the path.\n',  'Welcom to the desert of the real!\n']

 

 

 

많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~

'를 꾹 눌러주세요. :-)

 

 

 

반응형
Posted by Rfriend

댓글을 달아 주세요

이번 포스팅에서는 파이썬으로 


(1) 파일을 열고, 데이터를 쓰고, 파일을 닫기

(2) 파일을 열고, 데이터를 읽고, 파일을 닫기

(3) with open(file_name) as file_object: 로 파일 열고, 데이터를 읽고, 자동으로 파일 닫기

(4) open() error 처리 옵션 설정


하는 방법을 소개하겠습니다. 




파이썬으로 파일을 열 때 open() 함수를 사용하는데요, 1개의 필수 매개변수와 7개의 선택적 매개변수를 가지며, 파일 객체를 반환합니다. open() 함수의 mode 는 'w', 'r', 'x', 'a', '+', 'b', 't'의 7개 모드가 있으며, 위의 이미지 우측에 있는 표를 참고하시기 바랍니다. ('r' 읽기용으로 파일 열기't' 텍스트 모드로 열기가 기본 설정값입니다)



open(

  file,                 # 필수 매개변수, 파일의 경로

  mode = 'r',       # 선택적 매개변수, 'rt' (읽기용, text mode)가 기본값

  buffering = -1,   # 선택적 매개변수, 버퍼링 정책 (0 : binary mode 시 버퍼링 미수행, 

                        # 1: 텍스트 모드 시 개행문자(\n)을 만날 때까지 버퍼링)

  encoding = None, # 선택적 매개변수, 문자 인코딩 방식 (예: 'utf-8', 'cp949', 'latin' 등)

  errors = None,   # 선택적 매개변수, 텍스트 모드 시 에러 처리 (예: 'ignore' 에러 무시)

  newline = None, # 선택적 매개변수, 줄바꿈 처리 (None, '\n', '\r', '\r\n')

  closefd = True,   # 선택적 매개변수, False 입력 시 파일 닫더라도 파일 기술자 계속 열어둠

  opener = None) # 선택적 매개변수, 파일을 여는 함수를 직저 구현 시 사용

 




  (1) 파일을 열고 --> 파일에 데이터를 쓰고 --> 파일을 닫기


(1-1) MyFile = open('myfile.txt', 'w') : open() 함수를 사용하여 'myfile.txt' 파일을 'w' 모드 (쓰기용으로 파일 열기, 파일이 존재하지 않으면 새로 생성, 파일이 존재하면 파일 내용을 비움(truncate)) 열어서 MyFile 객체에 할당하고,  

(1-2) MyFile.write('data') : MyFile 객체에 'data'를 쓴 후에, 

(1-3) MyFile.close() : 파일을 닫습니다. 자원 누수 방지를 위해 마지막에는 꼭 파일을 닫아(close) 주어야 합니다. 


참고로, Windows 10 OS의 기본 encoding 은 'cp949' 입니다. 



# Open and Write

MyFile = open('myfile.txt', 'w')

MyFile.write('Open, read, write and close a file using Python')

MyFile.close()


# encoding = 'cp949' for Windows10 OS

MyFile

[Out] <_io.TextIOWrapper name='myfile.txt' mode='w' encoding='cp949'>

 



현재 작업 경로에 위에서 만든 'myfile.txt' 파일이 생성이 되어서 존재하는지 확인해보겠습니다. 



import os

os.listdir(os.getcwd())

[Out]:

['myfile.txt', 'Python_read_write_file.ipynb']

 




  (2) 파일을 열고 --> 파일의 데이터를 읽고 --> 파일을 닫기


(2-1) MyFile = open('myfile.txt', 'r') : 이번에는 (1)번에서 데이터를 써서 만들어놓은 'myfile.txt' 파일을 open() 함수의 'r' 모드 (읽기용으로 파일 열기, default) 로 열어서 MyFile 객체에 할당하고, 

(2-2) MyString = MyFile.read() : 'myfile.txt' 파일을 읽어서 MyString 객체에 데이터를 저장하고, print(MyString) 로 인쇄를 한 후, 

(2-3) MyFile.close() : 파일을 닫습니다. 자원 누수 방지를 위해 마지막에는 꼭 파일을 닫아(close) 주어야 합니다. 


# Open and Read

MyFile = open('myfile.txt', 'r')


# equivalent to the above

#MyFile = open('myfile.txt', 'rt')

#MyFile = open('myfile.txt', 't')

#MyFile = open('myfile.txt')


MyString = MyFile.read()

print(MyString)


[Out]: Open, read, write and close a file using Python


# close the 'MyFile' file

MyFile.close()



open() 함수의 7개 mode 중에서 'r' 읽기용으로 열기와 't' 텍스트 모드로 열기가 기본값이므로 위의 open('myfile.txt', 'r') 은 open('myfile.txt', 'rt'), open('myfile.txt', 't'), open('myfile.txt') 와 동일한 코드입니다. 




  (3) with open(파일 이름) as 파일 객체: 를 사용해서 파일 열기


with open() as 문을 사용하여 파일을 열면 마지막에 close() 함수를 명시적으로 써주지 않아도 자동으로 파일이 닫힙니다. 위의 (2) 번 코드를 with open(file_name) as file_object: 문으로 바꿔주면 아래와 같습니다. 



# Using the with statement the file is automatically closed

with open('myfile.txt', 'r') as MyFile:

    MyString = MyFile.read()

    print(MyString)

    # no need for MyFile.close()


[Out]: Open, read, write and close a file using Python

 




  (4) 텍스트 모드에서 인코딩, 디코딩 에러 발생 시 처리 : errors


가령, 파일에서 데이터를 읽거나 쓰는 와중에 에러가 발생했을 시 무시하고 싶다면 open('file.txt', 'rw', errors = 'ignore') 라고 설정을 해주면 됩니다. 


errors 매개변수 

error 처리 방법 

 'strict'

 인코딩 에러 발생 시 ValueError 예외

 'ignore'

 에러 무시

 'replace'

 대체 기호 삽입 (예: "?")

 'surrogateescape'

 U+DC80~U+DCFF 사이의 유니코드 사용자 자유 영역의 잘못된 바이트를 code points 로 나타냄

 'xmlcharrefreplace'

 파일을 쓸 때 파일에 기록하려는 텍스트 안의 지정된 인코딩에서 지원되지 않는 문자를 &#NNN; 의 XML 문자 참조로 바꿔서 기록

 'backslashreplace'

 파일을 쓸 때 현재 인코딩에서 지원되지 않는 문자를 역슬래시(back slash, \)로 시작되는 escape sequence로 바꿔서 기록



다음번 포스팅에서는 줄 단위로 텍스트 파일을 읽고 쓰는 방법을 소개하겠습니다. 


많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)


반응형
Posted by Rfriend

댓글을 달아 주세요

JAVA, C++, C#, Python, PHP 등을 사용하는 SW 개발자 중에 객체 지향 프로그래밍(Object-Oriented Programming, OOP)과 클래스(Class)를 모르는 분은 없을 것입니다. 


반면에, 통계와 데이터 분석을 전공하신 분들 중에는 객체 지향 프로그래밍과 클래스에 대해서 모르는 분이 상당히 많을 것이라고 보며, 아마도 '내가 개발자도 아닌데 객체 지향 프로그래밍과 클래스를 왜 알아야 해? 사용자 정의함수 만들어 쓸 수 있으면 되는거 아닌가?' 라고 생각하며 아예 선을 그어버리고 외면하는 분도 계실 듯 합니다. (제가 예전에 이랬거든요. ^^;)


그런데 통계/머신러닝 모델을 운영 시스템에 반영하기 위해 개발자와 협업하다보면 클래스 얘기가 나오고, 또 딥러닝 공부하다보니 자꾸 클래스와 맞닥드리게 되어서 이참에 클래스 공부도 하고 블로그에 정리도 하게 되었습니다. 


이번 포스팅에서는 통계와 분석업무 하시는 분들을 독자로 가정하고 파이썬3의 클래스(Class in Python 3)에 대해서 소개하겠습니다. 


1. 객체 지향 프로그래밍은 무엇이며, 클래스는 무엇인가? 

2. 왜 객체지향 프로그램이 필요한가?

3. 클래스와 인스턴스는 어떻게 만드는가? 

4. 클래스 상속이란 무엇인가? 

5. 클래스와 함수의 차이점은 무엇인가


ps. Private member, 상속의 super(), 다중 상속, decorator, iterator, generator, 추상 기반 클래스(abstract base class), Overriding 등의 세부 심화 내용은 이번 포스팅에서는 제외하겠으며, 파이썬 프로그래밍 개발 관련 전문 서적이나 사이트를 참고하시기 바랍니다. 



  1. 객체 지향 프로그래밍은 무엇이며, 클래스는 무엇인가? 


위키피디아에서 객체 지향 프로그래밍을 어떻게 정의하고 있는지 찾아보았습니다. 


객체 지향 프로그래밍(Object-oriented programming, OOP)은 객체(Objects) 개념에 기반한 프로그래밍 패러다임으로서, 변수(field) 혹은 속성(attribute), 특성(property)이라고 알려진 데이터(data)와 프로시져(procedures) 또는 메소드(methods) 형태의 코드(code) 를 가지고 있다. (Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data, in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).)


객체의 프로시져를 통해 객체의 연관되어 있는 데이터 변수들에 접근하고 변경할 수 있는 특성이 있다. (객체는 "this" 또는 "self"의 표기를 가지고 있다) (A feature of objects is an object's procedures that can access and often modify the data fields of the object with which they are associated (objects have a notion of "this" or "self").)


객체 지향 프로그래밍에서 컴퓨터 프로그램은 서로 상호작용하는 객체들을 만듦으로써 설계한다. 객체 지향 프로그래밍 언어는 다양하지만 가장 일반적인 것은 클래스 기반(class-based) 의 언어이다. 클래스 기반이란 클래스의 인스턴스가 객체가 되고 유형(type)을 결정하는 것을 의미한다. (In OOP, computer programs are designed by making them out of objects that interact with one another. OOP languages are diverse, but the most popular ones are class-based, meaning that objects are instances of classes, which also determine their types.)


* source: Wikipedia


말이 좀 어려운데요, 한번 더 정리를 해보자면, 

  • 객체(objects) = data (fields, attributes, properties) + code (procedures, methods)
  • code(procedures, methods) 를 통해 data(fields, attributes, properties)에 접근하고 변경 가능
  • class 로 data와 code를 겹합하며, 클래스를 구체화(실체화)한 인스턴스는 객체가 됨


Python도 객체 지향 프로그래밍을 지원하는 대표적인 언어이며, 위의 위키피디아 정의와 동일하게 객체는 속성(attribute)과 기능(method), 다른 말로 표현하면 객체는 변수(filed)와 함수(function)로 구성됩니다. 이들 속성(attribute)(또는 변수(field))와 기능(method)(또는 함수(function))을 클래스(class)를 사용해서 하나로 묶어줍니다. 클래스를 실체화하여 인스턴스(instance) 객체를 생성합니다. (아래 3번의 실제 예를 살펴보면 이해하기에 더 쉬울 것입니다)





  2. 왜 객체 지향 프로그램이 필요한가?


객체 지향 프로그래밍을 하면 객체(변수 + 함수) 내의 응집력은 강하지만 객체 간의 응집력은 약하게 하여 소프트웨어의 개발, 유지보수, 업그레이드를 보다 쉽게 할 수 있도록 해주는 장점이 있습니다. 


"객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용된다. 또한 프로그래밍을 더 배우기 쉽게 하고 소프트웨어 개발과 보수를 간편하게 하며, 보다 직관적인 코드 분석을 가능하게 하는 장점을 갖고 있다."

* source: wikipedia


"같은 목적과 기능을 위해 객체로 묶인 코드 요소(변수, 함수)들은 객체 내부에서만 강한 응집력을 발휘하고 객체 외부에 주는 영향은 줄이게 됩니다. 코드가 객체 위주로 (또는 순수하게 객체로만) 이루어질 수 있도록 지향하는 프로그래머의 노력은 코드의 결합도를 낮추는 결과를 낳게 됩니다."

* source: '뇌를 자극하는 파이썬3', 박상현 지음, 한빛미디어


아래의 클래스를 어떻게 만들고, 상속(inheritance)은 무엇인지를 알면 응집력에 대한 위의 내용이 좀더 이해가 쉬울 것입니다. 



  3. 클래스(class)와 인스턴스(instance)는 어떻게 만드는가? 




-- 클래스 정의 (create a Class) -- 

(a) 클래스 정의는 class 키워드 (keyword) 로 시작하고, 다음에 클래스 이름을 써주며, 뒤에 콜론(':')을 써줍니다. 


(b) 클래스 이름은 보통 대문자(capital letter)로 시작합니다. 

            아래 예) class PersonalInfo:


(c) 클래스의 코드 블락에는 

    (c-1) 클래스 전체에 공통으로 사용하는 클래스 속성(class attribute), 

            아래 예) nationality = "Korean"

   (c-2) 인스턴스별로 객체를 초기화해서 사용하는 인스턴스 속성(instance attributes)

            아래 예) def __init__(self, name, age):

                             self.name = name

                             self.age = age

   (c-3) 기능을 수행하는 인스턴스 메소드(instance methods) 를 정의합니다. 

            아래 예) def getPersonalInfo(self):

                             print("Name:", self.name)


(d) 인스턴스 객체의 속성을 초기화해주는 역할은 def __init__(): 의 마법 메소드(magic method) 를 사용합니다. 


(e) 'self'는 메소드가 소속되어 있는 객체를 의미합니다. ( C++, C#, JAVA 의 'this'와 동일한 역할)


-- 인스턴스 객체 생성 (create an instance object) --

(g) 클래스 이름(변수 값) 생성자로 클래스를 구체화/ 상세화한 인스턴스(instance)를 정의합니다. 

          아래 예) personal_choi = PersonalInfo('CK Choi', 25)




# class definition starts with 'class' keyword

# class name starts with the CAPITAL LETTER usually

class PersonalInfo:

    

    # Class attribute

    nationality = "Korean"

    

    # Initalizer, Instance attributes

    def __init__(self, name, age):

        self.name = name

        self.age = age

        

    # instance method 1

    def getPersonalInfo(self):

        print("Name:", self.name)

        print("Age:", self.age)

        

    # instance method 2

    def ageGroup(self):

        if self.age < 30:

            return "under 30"

        else:

            return "over 30"

        

    # instance method 3

    def FirstName(self):

        print(self.name.split(' ')[0])

    

    # instance method 4

    def LastName(self):

        print(self.name.split(' ')[1])

 




아래 코드는 클래스 생성 시점에 메모리에 같이 저장이 되고, 클래스 전체에서 공유하는 속성인 클래스 속성(class attribute) 값을 조회한 결과입니다. '클래스이름.속성이름'  의 형태로 조회합니다. 



# get class attribute

PersonalInfo.nationality

[Out]:'Korean'

 




아래의 코드는 클래스를 상세화/구체화하여 인스턴스 객체를 생성한 예입니다. 인스턴스 객체의 속성과 메소드는 인스턴스 객체를 생성하는 시점에 메모리에 저장이 됩니다.  


인스턴스 객체를 생성할 때마다 __init__(self) 의 마법 메소드(magic method)가 속성 값을 초기화(initialization) 해줍니다. 인스턴스 속성은 '인스턴스 객체 이름'에 점('.')을 찍고 뒤에 '속성 이름'을 써주면 조회할 수 있습니다.  

    아래 예) personal_choi.name


인스턴스 메소드 호출은 인스턴스 객체 이름에 점('.')을 찍고 뒤에 '메소드 이름()'을 써주면 됩니다. 

    아래 예) personal_choi.getPersonalInfo()


인스턴스 객체 1 (instance object 1)

인스턴스 객체 2 (instance object 2)


# instance

personal_choi = PersonalInfo('CK Choi', 25)


# get instance attribute

personal_choi.name

[Out]: 'CK Choi'


# instance method 1

personal_choi.getPersonalInfo()

[Out]:
Name: CK Choi
Age: 25


# instance method 2

personal_choi.ageGroup()

[Out]: 'under 30'


# instance method 3

personal_choi.FirstName()

[Out]: CK


# instance method 4

personal_choi.LastName()

[Out]: Choi



# instance

personal_park = PersonalInfo('SJ Park', 33)


# get instance attribute

personal_park.name

[Out]: 'SJ Park'

# instance method 1 personal_choi.getPersonalInfo()

[Out]: 
Name: SJ Park
Age: 33


# instance method 2

personal_park.ageGroup()

[Out]: 'over 30'

# instance method 3

personal_park.FirstName()

[Out]: SJ


# instance method 4

personal_park.LastName()

[Out]: Park





  4. 클래스 상속이란 무엇인가? 





부모가 자식에게 재산을 상속하듯이, 클래스도 클래스가 다른 클래스에게 상속을 해줄 수 있습니다. 상속을 해주는 클래스를 부모 클래스(Parent Class) 혹은 기반 클래스(Base Class) 라고 하며, 상속을 받는 클래스를 자식 클래스(Child Class) 혹은 파생 클래스(Derived Class)라고 합니다. 도형으로 표기할 때는 바로 위 그림의 예시처럼 '자식 클래스'에서 시작해서 '부모 클래스'로 향하는 화살표를 그려줍니다. 


부모 클래스를 생성한 후에 자식 클래스 이름 끝의 괄호() 안에 부모 클래스의 이름을 적어주면 자식 클래스가 부모 클래스의 모든 데이터 속성과 메소드를 유산으로 상속받아 부모 클래스처럼 역할을 할 수가 있습니다. 

    위의 그림 예) class ChildClass(ParentClass): 

                             pass



위의 '3. 클래스는 어떻게 만드는가?'에서 들었던 예제 클래스 PersonalInfo 를 부모 클래스로 하고, 이를 상속받은 자식 클래스를 class ContactInfo(PersonalInfo):  로 아래에 만들어보겠습니다. 부모 클래스에서 상속받은 데이터 속성, 메소드 외에 def getContactInfo(self, cellphone, city): 로 인스턴스 메소드를 추가로 정의해주었습니다. 



# Child(derived) class (inherits from PersonalInfo() parent(base) class)

class ContactInfo(PersonalInfo):

    def getContactInfo(self, cellphone, city):

        print("Name:", self.name)

        print("Age:", self.age)

        print("Celluar Phone:", cellphone)

        print("City:", city)

 



아래에는 contact_lee = ContactInfo('SH Lee', 41) 으로 위의 자식 클래스를 상세화한 contact_lee 라는 이름의 인스턴스 객체를 만들었습니다. 아래에 보시다시피 getPersonalInfo(), ageGroup(), FirstName(), LastName() 등의 부모 클래스에서 정의했던 인스턴스 메소드를 자식 클래스로 부터 생성한 인스턴스에서도 동일하게 사용할 수 있음을 알 수 있습니다. 



contact_lee = ContactInfo('SH Lee', 41)


# instance method from Parent class

contact_lee.getPersonalInfo()

[Out]:

Name: SH Lee Age: 41


# instance method from Parent class

contact_lee.ageGroup()

[Out]: 'over 30'


# instance method from Parent class

contact_lee.FirstName()

[Out]: SH


# instance method from Parent class

contact_lee.LastName()

[Out]: Lee


# -- instance method from Child class

contact_lee.getContactInfo('011-1234-5678', 'Seoul')

[Out]: 
Name: SH Lee
Age: 41
Celluar Phone: 011-1234-5678
City: Seoul





  5. 클래스와 함수의 차이점은 무엇인가


코드의 재사용성(reusability) 측면에서는 클래스와 함수가 유사한 측면도 있습니다만, 클래스와 함수는 엄연히 다릅니다. 클래스의 이해를 돕기 위해 마지막으로 한번 더 정리하는 차원에서 클래스와 함수의 차이점을 비교해보자면요, 



  • 클래스(class)는 같은 목적과 기능을 위해 '데이터 속성(변수)'과 '기능(함수)'를 결합해 놓은 집합체/그룹으로서, 객체 지향 프로그래밍에서 인스턴스 객체를 생성하는데 사용이 됩니다. 
  • vs. 함수(function)는 특정 기능/과업을 수행하는 코드 블록입니다. (A function is a unit of code devoted to carrying out a specific task)

클래스(class)가 함수(function) 보다 더 광범위한 개념이며, 함수는 클래스의 부분집합입니다. 


많은 도움이 되었기를 바랍니다.

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)



[Reference]

1. '뇌를 자극하는 파이썬3', 박상현 지음, 한빛미디어

2. Object-Oriented Programming in Python 3, by Real Python

3. Object-Oriented Programming, Wikipedia




반응형
Posted by Rfriend

댓글을 달아 주세요

이번 포스팅에서는 Jupyter Notebook을 사용하는데 있어 자주 쓰는 것은 아니지만 한번 쓰려고 하면 방법을 찾으려고 하면 또 시간을 빼앗기곤 하는, 그래서 어디에 메모해두었다가 필요할 때 꺼내쓰기에 아기자기한 팁들을 모아보았습니다. 

 

(1) Jupyter Notebook cell 너비 설정하기

(2) Jupyter Notebook에서 DataFrame 칼럼 최대 너비 설정하기

(3) Jupyter Notebook에서 DataFrame 내 텍스트를 왼쪽으로 정렬하기

(4) Jupyter Notebook에서 DataFrame 소수점 자리수 설정하기

(5) Jupyter Notebook에서 matplotlib plot 기본 옵션 설정하기 (figure size, line width, color, grid)

(6) Jupyter Notebook에서 출력하는 행의 최대개수 설정하기 (number of max rows) 

 

 

 (1) Jupyter Notebook cell 너비 설정하기 (setting cell width in Jupyter Notebook)

 

아래 코드의 부분의 숫자를 바꾸어주면 됩니다.  

 

 

from IPython.core.display import display, HTML

 

display(HTML("<style>.container { width: 50% !important; }</style>"))

 

 

 

 

 

 (2) Jupyter Notebook에서 DataFrame 칼럼 최대 너비 설정하기 

     (setting the max-width of DataFrame's column in Jupyter Notebook)

 

 

 

import pandas as pd

pd.set_option('display.max.colwidth', 10)

 

df = pd.DataFrame({'a': [100000000.0123, 20000000.54321], 

                  'b': ['abcdefghijklmnop', 'qrstuvwxyz']})

 

df

 

 
 
Out[2]:
  a b
0 1.0000... abcdef...
1 2.0000... qrstuv...

 

 
 
 
pd.set_option('display.max.colwidth', 50)
 
df
 
Out[3]:
 
 
  a b
0 1.000000e+08 abcdefghijklmnop
1 2.000000e+07 qrstuvwxyz
 

 

 

 

 

 

 (3) Jupyter Notebook에서 DataFrame 내 텍스트를 왼쪽으로 정렬하기 

     (align text of pandas DataFrame to left in Jupyter Notebook)

 

 

dfStyler = df.style.set_properties(**{'text-align': 'left'})

dfStyler.set_table_styles([dict(selector='th', 

                                props=[('text-align', 'left')])])

 

 
 
Out[4]:
  a b
0 1e+08 abcdefghijklmnop
1 2e+07 qrstuvwxyz

 

 

 

 

 

 (4) Jupyter Notebook에서 DataFrame 소수점 자리수 설정하기

     (setting the decimal point format of pandas DataFrame in Jupyter Notebook)

 

아래에 예시로 지수형 표기를 숫자형 표기로 바꾸고, 소수점 2째자리까지만 나타내도록 숫자 표기 포맷을 설정해보겠습니다. 

 

 

import pandas as pd

pd.options.display.float_format = '{:.2f}'.format

 

 

df

 
 
Out[6]:
  a b
0 100000000.01 abcdefghijklmnop
1 20000000.54 qrstuvwxyz

 

 

 

 

 

 (5) Jupyter Notebook에서 matplotlib plot 기본 옵션 설정하기 

    (setting figure size, line width, color, grid of matplotlib plot in Jupyter Notebook)

 

matplotlib.pyplot 의 plt.rcParams[] 를 사용하여 그래프 크기, 선 너비, 선 색깔, 그리드 포함 여부 등을 설정할 수 있습니다. 

 

 

# matplotlib setting

import matplotlib.pylab as plt

%matplotlib inline

 

plt.rcParams["figure.figsize"] = (6, 5)

plt.rcParams["lines.linewidth"] = 2

plt.rcParams["lines.color"] = 'r'

plt.rcParams["axes.grid"] = True

 

# simple plot

x = [1, 2, 3, 4, 5]

y = [2, 3.5, 5, 8, 9]

 

plt.plot(x, y)

plt.show()

 

 

 

 

 

 (6) Jupyter Notebook에서 출력하는 최대 행의 개수 설정하기 (number of max rows)

 

Jupyter Notebook 셀에서 DataFrame 인쇄 시에 기본 설정은 행의 개수가 많을 경우 중간 부분이 점선으로 처리 ("...")되어 건너뛰고, 처음 5개행과 마지막 5개 행만 선별해서 보여줍니다.   

 

 

# if there are many rows, JN does not print all rows

import pandas as pd
import numpy as np

 

df = pd.DataFrame(np.arange(200).reshape(100, 2))
df
 

 

 

 

그런데, 필요에 따라서는 전체 행을 프린트해서 눈으로 확인해봐야할 때도 있습니다. 이럴 경우 Jupyter Notebook에서 출력하는 최대 행의 개수 (the number of max rows in Jupyter Notebook) 를 설정할 수 있습니다. 위의 예에서 5번째 행부터 점선으로 처리되어 건너뛰고 안보여지던 행이, pd.set_option('display.max_rows', 100) 으로 최대 인쇄되는 행의 개수를 100개로 늘려서 설정하니 이번에는 100개 행이 전부 다 인쇄되어 볼 수 있습니다. 

 

 

# setting the number of maximum rows in Jupyter Notebook

import pandas as pd

pd.set_option('display.max_rows', 100)

df
 

 

 

 (7) Jupyter Notebook에서 출력하는 최대 열의 개수 설정하기 (number of max columns)

 

Jupyter Notebook 셀에서 DataFrame 인쇄 시에 기본 설정은 열의 개수가 20개를 넘어가면 중간 부분이 점선으로 처리 ("...")되어 건너뛰고, 나머지 20개만 출력을 해줍니다.  아래의 화면 캡쳐 예시처럼 중간 열 부분의 결과가 "..." 으로 가려져있어서 확인할 수가 없습니다. 

 

 

이럴 경우에 pandas.set_option('display.max.columns', col_num) 옵션을 사용하여 화면에 보여주는 최대 열의 개수 (maximum number of columns)"를 옵션으로 설정해줄 수 있습니다.   위에서는 ... 으로 처리되었던 열10 ~ 열12 가 아래에서는 제대로 jupyter notebook에 출력되었네요!

 

 

# setting the maximum number of columns in jupyter notebook display

import pandas as pd

 

pd.set_option('display.max.columns', 50) # set the maximum number whatever you want
 

 

 

많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~

'를 꾹 눌러주세요. :-)

 

 

반응형
Posted by Rfriend

댓글을 달아 주세요