본문 바로가기
BOOSTCAMP AI TECH/1주차_Python Basics For AI

[BOOSTCAMP AI TECH] 5일차_파이썬으로 데이터 다루기

by 이민우 2021. 1. 22.
728x90
반응형
  • 강의 목록

-File / Exception / Log Handling

-Python data handling

-특강


  • 요약

강의

파이썬에서의 파일 입출력, 예외 처리, 로그 처리를 학습했다.

파이썬에서의 다양한 파일 입출력을 학습했다.

특강에서 최 교수님의 다양한 이야기와 설명을 들었다. 여러가지 깊은 생각을 할 수 있게 만들어주신 의미있는 강의였다.

 

피어세션

전날 강의를 복습하고, 모더레이터가 작성한 과제를 토대로 코드리뷰 시간을 가졌다.


  • 학습정리

예외 (Exception)

  • 예상 가능한 예외와 예상이 불가능한 예외가 있다.
  • 인터프리터 과정에서 발생하는 예외나 개발자의 실수가 있다.
  • 리스트의 범위를 넘어가는 값 호출, 정수를 0으로 나누기 등이 그 예시이다.
  • 수행 불가시 인터프리터가 자동 호출한다.
  • 예외가 발생할 경우 후속 조치 등의 대처가 필요하다 (예외처리, Exception Handling)

 

예외처리 (Exception Handling)

  • 파이썬에서는 try, except 문법을 사용한다.
  • try, except, finally 문으로 이루어져 있으며, except 다음에 else를 부착하면 예외 미발생시 상황에 대한 처리도 가능하다.
  • raise를 활용하면 강제로 Exception을 일으킬 수 있다 (Java의 throw)
  • assert를 활용해 특정조건 미만족시 예외를 발생시킬 수도 있다.
#--Exception--#

try :
    i = 10/10 #ZeroDivisionError
    #raise ZeroDivisionError 로 throw 가능
except ZeroDivisionError as err :
    print(err) #division by zero
else : #예외 미발생시 실행
    print('에러 발생 안하넹!')
finally :
    print('end zero division')


try :
    print(a) #NameError : 존재하지 않는 변수
    l = [1,2,3]
    print(l[4]) #IndexError : 인덱스 범위 초과
    print(int('abc')) #ValueError : 변환할 수 없는 문자/숫자
    f = open('abc.txt', 'r', encoding='utf8') #FileNotFoundError : 존재하지 않는 파일
    
    assert isinstance('100', int) #100이 int인가? Exception으로 넘어감
except NameError as err :
    print(1, err)
except IndexError as err :
    print(2, err)
except ValueError as err :
    print(3, err)
except FileNotFoundError as err :
    print(4, err)
except Exception as err :
    print(5, err) #기타 모든 에러
else : #예외 미발생시 실행
    print('에러 발생 안하넹!')
finally :
    print('end of Error')


class MyException (Exception) :
    def __init__(self, msg) :
        super().__init__(msg)

try : 
    raise MyException('사용자 정의 에러')
except MyException as err :
    print(err) #사용자 정의 에러

 

파일 시스템 (File System)

  • OS에서 파일을 저장하는 트리구조 저장 체계

 

파일 (File)

  • 컴퓨터 등의 기기에서 의미 있는 정보를 담는 논리적인 단위
  • 모든 프로그램은 파일로 구성되어 있고 파일을 사용한다.
  • 파일은 파일명과 확장자로 식별된다.
  • 실행, 쓰기, 읽기 등을 할 수 있다.
  • Text 파일과 Binary 파일로 구분되며, 모든 텍스트 파일은 이진 파일이다.
  • 컴퓨터는 텍스트 파일을 처리하기 위해 이진 파일로 변환시킨다.

 

파이썬의 파일처리

  • open 키워드를 사용한다.
  • f = open ("파일명“, ”접근모드“, encoding='utf8')
  • 접근모드 : r (읽기) / w (덮어쓰기) / a (추가)
#--file read--#
#읽기
f = open('test.txt', 'r', encoding='utf8')
contents = f.readlines() #전체 읽기
print(contents) #['gdgdgd.\n', 'ddgdgdg']
f.close()

with open("test.txt", "r", encoding='utf8') as f :
    contents = f.readlines()
    print(contents, type(contents)) #['gdgdgd.\n', 'ddgdgdg'] <class 'list'>
#with로 해서 별도의 close 필요없음

#쓰기
f = open('test.txt', 'w', encoding='utf8')
f.write('gdgdgd.\n')
f.write('ddgddg')
f.close()

with open('test.txt', 'w', encoding='utf8') as f:
    f.write('gdgdgd.\n')
    f.write('ddgddg')

 

 

디렉토리 (Directory)

  • 폴더라고도 부름
  • 파일과 다른 디렉토리를 포함할 수 있다.
#--directory--#
import os
#os.mkdir("log") #log폴더 생성

if not os.path.isdir("log") :
    #os.path.exists("log") #이렇게 확인도 가능
    os.mkdir("log") #폴더가 있으면 에러발생해서 이렇게 확인하고 생성

filename = 'test.txt'
dest = os.path.join("log", filename)
print(dest) #log\test.txt

#pathlib으로 path를 객체로 다룰 수도 있음
import pathlib
cwd = pathlib.Path.cwd()
print(cwd) #현재 path
print(cwd.parent) #부모 디렉토리
print(list(cwd.parents)) #모든 부모 디렉토리
print(list(cwd.glob('*'))) #현재 폴더의 모든 파일들의 path

 

Pickle

  • 파이썬의 객체를 영속화 (Persistence)하는 객체
  • 데이터, object 등의 실행중 정보를 그대로 저장한다.
  • 나중에 그대로 불러와서 사용할 수 있다.
  • 저장해야 하는 정보, 계산 결과 등에 활용한다.
#--pickle--#
import pickle
f = open('test.pickle', 'wb')
test = [1,2,3,4,5]
pickle.dump(test, f)
f.close()
#Binary 파일로 입력해서 글자는 깨진 것처럼 보임

f = open('test.pickle', 'rb')
test = pickle.load(f)
print(test) #[1, 2, 3, 4, 5]
f.close()

 

로그 남기기 (Logging Handling)

  • 프로그램의 실행중 일어나는 정보를 기록하는 것
  • 유저의 접근, 예외, 특정 함수 사용 등
  • 콘솔 화면에 출력, 파일에 남기기, 데이터베이스에 저장 등
  • 기록된 로그를 분석하면 의미있는 결과 도출이 가능하다.
  • 실행시점에서 남겨야 하는 기록과 개발시점에 남겨야 하는 기록이 존재한다.
  • 모듈별로 별도의 로깅을 남길 필요가 있다.
  • 로깅을 수행하는 체계적인 모듈이 필요하다.

 

Logging level

  • 프로그램 진행 상황에 따라 다른 레벨의 log 출력

#--logging--#
import logging

#어디에 저장할지.
logger = logging.getLogger("main")
stream_handler = logging.FileHandler("logfile.log", mode='a', encoding='utf8')
logger.addHandler(stream_handler)

#어디부터 출력할지 결정
logger.setLevel(logging.DEBUG) #logging.(레벨) 이후 다 출력

logger.debug("개발 중 처리 기록 : 변수 a를 이렇게 변경함")
logger.info("처리가 진행되는 동안 : 서버가 시작됨, 사용자가 접속")
logger.warning("개발 의도와 다른 정보가 입력됨 : str 입력하라니까 왜 int 넣음")
logger.error("잘못된 처리로 인해 에러 발생. 프로그램 동작은 가능")
logger.critical("잘못된 처리로 인해 에러 발생. 프로그램 동작 불가")

#포맷 설정 가능
formatter = logging.Formatter('%(asctime)s %(levelname)s %(process)d %(message)s')
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)

logger.setLevel(logging.DEBUG) #logging.(레벨) 이후 다 출력

logger.debug("개발 중 처리 기록 : 변수 a를 이렇게 변경함")
logger.info("처리가 진행되는 동안 : 서버가 시작됨, 사용자가 접속")
logger.warning("개발 의도와 다른 정보가 입력됨 : str 입력하라니까 왜 int 넣음")
logger.error("잘못된 처리로 인해 에러 발생. 프로그램 동작은 가능")
logger.critical("잘못된 처리로 인해 에러 발생. 프로그램 동작 불가")

 

Configparser

  • 프로그램의 실행 설정을 파일에 저장
  • 섹션, 키, 밸류 값의 형태로 설정된 설정 파일을 사용한다.
  • 설정파일을 Dict 타입으로 호출해 사용한다.
#--configparser--#
import configparser
config = configparser.ConfigParser()
config.sections() #섹션은 대괄호, 속성은 키:밸류
'''
[Section1]
Status: Single
Name: Derek
Value: Yes
Age: 30
Single: True
[Section2]
FavoriteColor = Green
'''

config.read("ex.cfg")
config.sections()

for key in config['Section1'] :
    print(key)
print(config['Section2']['FavoriteColor']) #Green

 

Argparser

  • 콘솔 창에서 실행시 세팅 정보를 저장
  • 거의 모든 콘솔 기반 파이썬 프로그램 기본으로 제공
  • TF등도 있지만 일반적으로 argparser를 사용
  • COMMAND-LINE OPTION이라고 부름
#--argparse--#

import argparse
parser = argparse.ArgumentParser(description='Sum two integers.')
parser.add_argument('-a', "--a_value", dest="A_value", help="A integers", type=int)
#짧은 이름과 긴 이름을 동시에 지정해 둘 다 사용 가능하게.
parser.add_argument('-b', "--b_value", dest="B_value", help="B integers", type=int)
args = parser.parse_args()
print(args)
print(args.a)
print(args.b)
print(args.a + args.b)

#기본 옵션 지정
parser = argparse.ArgumentParser(description='PyTorch MNIST Example')
parser.add_argument('--batch-size', type=int, default=64, metavar='N', help='input batch size for training (default:64)')
parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N', help='input batch size for testing(default: 1000)')
parser.add_argument('--epochs', type=int, default=10, metavar='N', help='number of epochs to train (default: 10)')
parser.add_argument('--lr', type=float, default=0.01, metavar='LR', help='learning rate (default: 0.01)')
parser.add_argument('--momentum', type=float, default=0.5, metavar='M', help='SGD momentum (default: 0.5)')
parser.add_argument('--no-cuda', action='store_true', default=False, help='disables CUDA training')
parser.add_argument('--seed', type=int, default=1, metavar='S', help='random seed (default: 1)')
parser.add_argument('--save-model', action='store_true', default=False, help='For Saving the current Model')
args = parser.parse_args() 

 

Comma Separate Value (CSV)

  • 필드를 쉼표로 구분한 텍스트 파일
  • 엑셀 양식의 데이터를 프로그램에 상관없이 사용하기 위한 데이터 형식
  • 탭, 빈칸 등으로 구분해 만들기도 한다.
  • 파이썬에서는 csv 객체를 제공해 간단하게 CSV 파일을 처리할 수 있다.

#--CSV--#
import csv
seoung_nam_data = []
header = []
rownum = 0

#읽어오기
with open("korea_floating_population_data.csv","r", encoding="cp949") as p_file:
    csv_data = csv.reader(p_file) #csv 객체를 이용해서 csv_data 읽기
    for row in csv_data: #읽어온 데이터를 한 줄씩 처리
        if rownum == 0:
            header = row #첫 번째 줄은 데이터 필드로 따로 저장
    location = row[7]
    #“행정구역”필드 데이터 추출, 한글 처리로 유니코드 데이터를 cp949로 변환
    if location.find(u"성남시") != -1:
        seoung_nam_data.append(row)
    #”행정구역” 데이터에 성남시가 들어가 있으면 seoung_nam_data List에 추가
    rownum +=1

#쓰기
with open("seoung_nam_floating_population_data.csv","w", encoding="utf8") as s_p_file:
    writer = csv.writer(s_p_file, delimiter='\t', quotechar="'", quoting=csv.QUOTE_ALL)
    # csv.writer를 사용해서 csv 파일 만들기 delimiter 필드 구분자
    # quotechar는 필드 각 데이터는 묶는 문자, quoting는 묶는 범위
    writer.writerow(header) #제목 필드 파일에 쓰기
    for row in seoung_nam_data:
        writer.writerow(row) #seoung_nam_data에 있는 정보 list에 쓰기

 

Web (World Wide Web, WWW)

  • 인터넷 공간의 정식 명칭
  • 팀 버너스리에 의해 1989년 처음 제안되었다.
  • 원래는 물리학자들간 정보 교환을 위해 사용됨
  • 데이터 송수신을 위해 HTTP 프로토콜 사용
  • 데이터를 표현하기 위해 HTML 형식 사용

 

Web의 동작 과정

  1. 사용자가 서버에 요청 : 웹주소, From, Header 등을 전송한다.
  2. 서버가 처리 : 요청에 대응하여 DB 처리 등을 수행한다.
  3. 서버가 사용자에 응답 : HTML, XML 등으로 결과를 반환
  4. 랜더링 : HTML, XML를 표시하여 사용자에게 출력한다.

 

HTML (Hyper Text Markup Language)

  • 웹 상의 정보를 구조적으로 표현하기 위한 언어
  • 제목, 단락, 링크 등 요소 표시를 위해 태그를 사용
  • 모든 요소들은 꺾쇠 괄호 ( <> ) 안에 둘러쌓여있다.
  • 모든 HTML은 트리 모양의 포함 관계를 가진다
  • 일반적으로 웹 페이지의 HTML 소스파일은 컴퓨터가 다운받아 웹 브라우저가 해석해서 표시
  • HTML도 일종의 프로그램으로 페이지 생성 규칙이 있어 규칙을 분석해 데이터 추출이 가능하다.

 

정규식 (Regular Expression)

  • 정규 표현식, regexp 또는 regex 등으로 불린다.
  • 복잡한 문자열 패턴을 정의하는 문자 표현 공식
  • 특정한 규칙을 가진 문자열의 집합을 추출한다.
  • HTML의 Tag를 형식으로 지정하면 파싱이 용이하다.
  • 파이썬에서는 re모듈을 활용해 사용할 수 있다.

#--urllib--#

import re
import urllib.request

url = "http://bit.ly/3rxQFS4"
html = urllib.request.urlopen(url)
html_contents = str(html.read())
id_results = re.findall(r"[A-Za-z0-9]+\*\*\*", html_contents)

for result in id_results :
    print(result)

url = "http://finance.naver.com/item/main.nhn?code=005930"
html = urllib.request.urlopen(url)
html_contents = str(html.read().decode("ms949"))

stock_results = re.findall("(\<dl class=\"blind\"\>)([\s\S]+?)(\<\/dl\>)", html_contents)
samsung_stock = stock_results[0] # 두 개 tuple 값중 첫번째 패턴
samsung_index = samsung_stock[1] # 세 개의 tuple 값중 두 번째 값
# 하나의 괄호가 tuple index가 됨

index_list= re.findall("(\<dd\>)([\s\S]+?)(\<\/dd\>)", samsung_index)
for index in index_list:
    print (index[1]) # 세 개의 tuple 값중 두 번째 값

 

 

 

 

XML (eXtensible Markup Language)

  • 데이터의 구조와 의미를 설명하는 태그를 사용하여 표시하는 언어
  • 태그와 태그 사이에 값이 표시되고 구조적인 정보 표현이 가능
  • HTML과 문법이 비슷한 대표적인 데이터 저장 방식
  • 정보의 구조에 대한 정보인 스키마와 DTD 등으로 정보에 대한 정보(메타정보)가 표현되며, 용도에 따라 다양한 형태로 변환이 가능하다.
  • 컴퓨터간, 혹은 PC-스마트폰간 정보교환에 매우 유용한 저장 방식으로 쓰인다.
  • HTML과 같은 구조적 Matkup 언어이다.
  • 정규표현식으로 파싱이 가능하다.
  • beautifulsoup으로 파싱이 가능하다. (가장 많이 쓰임)
#--XML--#
'''
<books>
    <book>
        <author>Carson</author>
        <price format="dollar">31.95</price>
        <pubdate>05/01/2001</pubdate>
    </book>
    <pubinfo>
        <publisher>MSPress</publisher>
        <state>WA</state>
    </pubinfo>
    <book>
        <author>Sungchul</author>
        <price format="dollar">29.95</price>
        <pubdate>05/01/2012</pubdate>
    </book>
    <pubinfo>
        <publisher>Gachon</publisher>
        <state>SeoungNam</state>
    </pubinfo>
</books>
'''
from bs4 import BeautifulSoup
with open("books.xml", "r", encoding="utf8") as books_file:
    books_xml = books_file.read() # File을 String으로 읽어오기

soup = BeautifulSoup(books_xml, "lxml") # lxml Parser를 사용해서 데이터 분석

# author가 들어간 모든 element 추출
for book_info in soup.find_all("author"):
    print (book_info)
    print (book_info.get_text())
    
import urllib.request
f = urllib.request.urlopen('https://s3.ap-northeast-2.amazonaws.com/teamlab-gachon/US08621662-20140107.XML')
f = str(f.read().decode("ms949"))
with open('US08621662-20140107.XML', 'w', encoding='utf8') as sav :
    sav.write(f)

with open("US08621662-20140107.XML","r", encoding="utf8") as patent_xml:
    xml = patent_xml.read() # File을 String으로 읽어오기
    
soup = BeautifulSoup(xml,"lxml") #lxml parser 호출

#invention-title tag 찾기
invention_title_tag = soup.find("invention-title")
print (invention_title_tag.get_text())

 

BeautifulSoup

  • HTML, XML 등 마크업 언어 스크래핑을 위한 도구
  • lxml과 html5lib과 같은 파서 사용
  • 속도는 상대적으로 느리지만 간편한 사용이 가능하다.
import urllib.request
from bs4 import BeautifulSoup

f = urllib.request.urlopen('https://s3.ap-northeast-2.amazonaws.com/teamlab-gachon/ipa110106.XML')
f = str(f.read().decode('ms949'))
with open('ipg140107.xml', 'w', encoding='utf8') as sav :
    sav.write(f)

with open('ipg140107.xml', 'r', encoding='utf8') as xml_file :
    xml_str = xml_file.read()

soup = BeautifulSoup(xml_str, "lxml")
print(soup)

 

 

JSON (JavaScript Object Notation)

  • 자바 스크립트의 데이터 객체 표현 방식
  • 간결성으로 기계와 인간 모두 이해하기 편함
  • 데이터 용량이 적고 코드로의 전환이 쉬움
  • XML의 대체제로 많이 사용됨
  • KEY : VALUE 쌍으로 데이터를 표시한다.
  • Python의 dict 타입과 상호 교환이 가능하다.
  • json 모듈을 활용해 손 쉽게 파싱 및 저장이 가능하다.
dic = {"employees":[
    {"firstName":"John", "lastName":"Doe"},
    {"firstName":"Anna", "lastName":"Smith"},
    {"firstName":"Peter", "lastName":"Jones"}
]}

import json
#쓰기
with open("json_example.json", "w", encoding = "utf8") as f :
    json.dump(dic, f)
#읽기
with open("json_example.json", "r", encoding="utf8") as f:
    contents = f.read()
    json_data = json.loads(contents)
    print(json_data["employees"])

  • 피어세션 회의 내용

dict(map(reversed, xxx.items())) 하면 키와 밸류가 바뀐 dict 반환 가능


  • 해야할 일

 

728x90
반응형