본문 바로가기
Python 과 머신러닝/I. 기초 문법

Python 기초 7장. 파일 입출력

by JoyfulS 2019. 10. 10.

< 공부한 내용 >

1. 예외처리

2. text파일 입출력

3. text파일 입출력 활용

4. csv, excel 파일 입출력

5. json 파일 입출력

 

1. 예외처리

'''
예외처리 : run time error 발생 시 처리
- file/DB 입출력 시 사용

try :
     예외가 발생할 수 있는 코드
except :
     예외를 처리할 수 있는 코드
finally :
     항상 실행되는 코드
'''

# 1. 간단한 예외처리 예
x = [10, 20, 25, 'num', 40, 50]

for i in x :
     try :
          print(i)
          y = i**2 # error 발생
          print('y=', y)
     except :
          print('숫자 아님!!')

print('프로그램 종료')

 

# try-exept문이 없으면 오류가 발생하는 지점에서 출력이 종료되나,

# try-except문을 사용함으로써 해당 오류를 어떻게 처리할지 지정하고 그 이후의 작업을 계속할 수 있음

 

# 2. 유형별 예외처리

 

# 1) 산술적 예외

try :
     div = 1000 / 2.5
     print('div=', div)
     div2 = 1000 / 0    # 산술적 예외

     print('div2=', div2)

except ZeroDivisionError as e:    # e 변수 : 예외정보를 받는 변수
     print('예외처리 영역1 :', e)  # 출력 : 예외처리 영역1 : division by zero
finally :
     print('항상 실행되는 영역')

 

# 2) 파일 열기 예외

try :
     f = open("c:/text.txt")  # 파일 열기 예외(파일이 없는 경우)
except FileNotFoundError as e:
     print('예외처리 영역2 :', e)  # 출력 : 예외처리 영역2 : [Errno 2] No such file or directory: 'c:/text.txt'
finally :
     print('항상 실행되는 영역')

 

# 3) 기타 예외
try :
     num = int(input("숫자 입력 : "))  # 기타 예외
     print('num=', num)
except Exception as e :
     print('기타 예외처리 영역3 :', e)  # 출력 : 기타 예외처리 영역3 : invalid literal for int() with base 10: '도레미'
finally :
     print('항상 실행되는 영역')

 

 

'''

다중 예외처리도 가능함

try :
     예외가 발생할 수 있는 코드
except ZeroDivisionError as I :
     산술적 예외를 처리할 수 있는 코드

except FileNotFoundError as II :
     파일열기 예외를 처리할 수 있는 코드

except Exception as e :

     (Exception은 가장 상위에 있는 오류처리라고 보면 됨

     -> 무슨 예외인지 모르는 경우에도 사용 가능. 어떤 오류든 받음)

     기타 예외를 처리할 수 있는 코드

else :
     예외가 없을 때 실행되는 코드
'''

 

 

2. text파일 입출력

'''
텍스트 파일 입출력
형식) open(file='파일경로/파일명', mode='r/w/a')
     mode='r' : 파일 읽기
     mode='w' : 파일 쓰기
     mode='a' : 파일 쓰기 + 추가
'''

import os  # os 모듈 import
print(os.getcwd())  # 기본 작업 디렉터리 반환
# C:\3_Pywork-I\workspace

# 파일 경로를 입력할 땐 기본 작업 디렉터리 확인 후 그 뒤의 경로만 입력하면 됨

 

# 다음 파일을 '파일 읽기'에서 사용해보기

ftest.txt
0.00MB


try :
     # 1. 파일 읽기 : 디렉터리 or 파일 구분자 : '/' or '\\'

     f = open(file='chap07_FileIO/Data/ftest.txt', mode='r') # mode='r' 생략 가능
     print(f.read()) # 문장 출력


     # 2. 파일 쓰기
     f2 = open(file='chap07_FileIO/Data/ftest2.txt', mode='w')   # ftest2.txt 파일이 새로 생성됨
     f2.write("This is my first text")

     # 3. 파일 쓰기 + 추가
     f3 = open(file='chap07_FileIO/Data/ftest2.txt', mode='a')
     f3.write("\nand this is my second text")

     # 4. 파일 읽기 객체 지원 함수
     '''
     obj.read() : 전체 문서 읽기
     obj.readLines() : 줄 단위 전체 문서 읽기
     obj.readline() : 한 줄 단위 읽기

`    ※  객체를 한번 읽어오면 그 객체는 빈 객체가 되어

         다시 읽어도 아무 것도 출력되지 않으므로

         다시 읽고 싶다면 새로 객체를 생성해야 함

     '''

'''

다음에 만든 f4 객체를 재사용하기 위해 '전체 문서 읽기' 결과를 확인한 후 주석처리, '줄 단위 전체 읽기' 결과를 확인한 후 주석처리, 마지막으로 '한 줄 단위 읽기' 결과를 확인하는 순서로 진행

'''

     f4 = open(file='chap07_FileIO/Data/ftest.txt') # mode='r' 생략


     print("전체 문서 읽기")
     #print(f4.read())


     print("줄 단위 전체 읽기")
     #lines = f4.readlines()
     #print(lines) # list 반환
     #print(len(lines)) # 6

     st = "afagba12sga \n \r \t"
     st2 = st.strip() # 문자열 끝에 오는 불용어 제거
     print(st2)  # afagba12sga

     print("한 줄 단위 읽기")
     doc = [ ] # list
     for i in range(6) :
          line = f4.readline()
          print(line.strip()) # line = programming is fun[\n]
          doc.append(line.strip()) # 문서 추가

      print('doc=', doc)

 

     # with문 이용한 파일 입출력
     with open(file="chap07_FileIO/Data/ftest.txt", mode='r') as f5 :
          f5.read()
     with open(file="chap07_FileIO/Data/ftest3.txt", mode='w', encoding='utf-8') as f6 :
          f6.write("파이썬 파일 작성 연습")

except FileNotFoundError as e :
     print('해당 파일이 없습니다.')
finally :
     print('파일 객체 닫기')
     f.close() # 파일 객체 닫기
     f2.close()
     f3.close()
     f4.close()
     f5.close()
     f6.close()

3. text파일 입출력 활용

'''

 - 다음과 같은 형태의 텍스트 파일을 이용할 것

[우편번호]tab[/]tab[]tab[]tab[세부주소]


135-806     서울     강남구     개포1동 경남아파트      1
    [0]         [1]         [2]           [3]              - 인덱스 번호
135-807     서울     강남구     개포1동 우성3차아파트     (16)      2
    [0]         [1]         [2]           [3]                               [4]
'''

zipcode.txt
2.88MB


# 동 이름 입력해서 우편번호 출력받기

import os
print(os.getcwd())  # C:\3_Pywork-I\workspace

try :
     dong = input("동을 입력하세요 : "# '개포' 입력
     f = open(file="chap07_FileIO/Data/zipcode.txt", mode='r', encoding='utf-8'

     line = f.readline() # 첫줄 읽기

     while line :  # 내용이 있으면 True, 없으면 False
          addr = line.split(sep='\t') # tab키 분리
          #print(addr) # ['\ufeff135-806', '서울', '강남구', '개포1동 경남아파트', '', '1\n']
          if addr[3].startswith(dong) :
               print('['+addr[0]+']', addr[1], addr[2], addr[3], addr[4])

     line = f.readline() # 두번째 줄 읽기

except Exception as e :
     print('예외 발생 : ', e)

finally :
     f.close

4. csv, excel 파일 입출력

# 1. csv 파일 읽기
import pandas as pd   # as pd : pd라는 별칭 사용

# 만약 pandas가 없어서 import가 안된다면 다음 화면에서 라이브러리 설치!

File - Settings 들어간 후 이 화면에서 우측 상단에 '+' 표시 눌러 필요한 라이브러리 검색해서 설치!

import os
print(os.getcwd()) # C:\3_Pywork-I\workspace

 

bmi.csv
0.27MB


################
## bmi.csv
################
bmi_data = pd.read_csv("chap07_FileIO/Data/bmi.csv", encoding='utf-8')
print(bmi_data.info())  # str(data)
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20000 entries, 0 to 19999
Data columns (total 3 columns):
height 20000 non-null int64
weight 20000 non-null int64
label 20000 non-null object
dtypes: int64(2), object(1)
'''
print(bmi_data.head())  # head - 위에서 5개 데이터 보여줌
print(bmi_data.tail())    # tail - 아래에서 5개 데이터 보여줌

# 칼럼을 vector 형태로 뽑아내기 (두 가지 방법)
height = bmi_data.height # 객체.칼럼명
weight = bmi_data['weight'] # 객체['칼럼명']
label = bmi_data['label']

# 키와 몸무게 평균
print('키 평균 :', sum(height)/len(height)) # 키 평균 : 164.9379
print('몸무게 평균 :', sum(weight)/len(weight)) # 몸무게 평균 : 62.40995

# 가장 큰 키와 몸무게
print('max height =', max(height)) # max height = 190
print('max weight =', max(weight)) # max weight = 85

# label 빈도수
label_count = {} # set

for key in label :
     label_count[key] = label_count.get(key, 0) + 1

print(label_count) # dict
# {'thin': 4898, 'normal': 7677, 'fat': 7425}

 

spam_data.csv
0.00MB


####################
## spam_data.csv
####################
spam_data = pd.read_csv("chap07_FileIO/Data/spam_data.csv", header=None, encoding='ms949')
print(spam_data.info())
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 2 columns):
0 5 non-null object
1 5 non-null object
dtypes: object(2)
'''
target = spam_data[0# ham/spam 메일 구분
texts = spam_data[1]    # 메시지 내용

print(target)
print(texts)

# target -> 더미변수(spam=1, ham=0)
target = [ 1 if t == 'spam' else 0 for t in target ]
print(target) # [0, 1, 0, 1, 0]

# texts -> 텍스트 전처리(특수문자, 숫자, 공백, 영문 제거 => 한글 단어만)
import re

def clean_text(text_string) :
     # 문장부호 제거
     texts_re = re.sub('[,.?!:;]', ' ', text_string)
     # 특수문자, 숫자 제거
     texts_re = re.sub('[@#$%^&]|[0-9]', ' ', texts_re)
     # 영문자 제거 : 소문자로 변경 -> 제거
     texts_re = texts_re.lower()
     texts_re = re.sub('[a-z]', ' ', texts_re)
     # 공백 제거
     texts_re = ' '.join(texts_re.split()) # 한칸 이상의 공백을 한칸으로
     return texts_re

clean_text_re = [clean_text(t) for t in texts]
clean_text_re
# ['우리나라 대한민국 우리나라 만세', '비아그라 정력 최고', '나는 대한민국 사람', '보험료 원에 평생 보장 마감 임박', '나는 홍길동']


# 2. excel 파일 읽기 : 'xlrd' 라이브러리 설치

sam_kospi.xlsx
0.02MB


sam = pd.ExcelFile("chap07_FileIO/Data/sam_kospi.xlsx")
# ImportError: Missing optional dependency 'xlrd'.

File - Settings 들어간 후 이 화면에서 우측 상단에 '+' 표시 눌러 필요한 라이브러리 검색해서 설치!

print(sam) # <pandas.io.excel._base.ExcelFile object at 0x16608D50>

kospi = sam.parse("sam_kospi"# "sam_kospi" : 워크시트 이름
print(kospi) # [247 rows x 6 columns]
print(kospi.info())
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 247 entries, 0 to 246
Data columns (total 6 columns):
Date 247 non-null datetime64[ns]
Open 247 non-null int64
High 247 non-null int64
Low 247 non-null int64
Close 247 non-null int64
Volume 247 non-null int64
'''

high = kospi['High']
low = kospi['Low']

from statistics import mean
print('high mean =', mean(high))
print('low mean =', mean(low))

 

5. json 파일 입출력

'''
json file : 네트워크 상에서 표준으로 사용되는 파일 형식
구성 : {key:value, key:value, ...}

json 모듈 기능
1. encoding : Python 객체(dict, list) -> json 문자열(json file)
2. decoding : json 문자열(json file) -> Python 객체(dict, list)
'''

import json # json file 처리 모듈

# 1. encoding
'''
Python 객체(dict, list) -> json 문자열(json file)
형식) json.dumps(object)
'''

# python 객체 생성
user = {'id' : '1234', 'name' : '홍길동'}
print(type(user)) # <class 'dict'>

# json 문자열로 변환
jsonStr = json.dumps(user) # object -> json
print(type(jsonStr)) # <class 'str'>


# 2. decoding
'''
json 문자열(json file) -> Python 객체(dict, list)
형식) json.loads(json string)
'''

# json 문자열
jsonStr = json.dumps(user)
print(jsonStr) # {"id": "1234", "name": "\ud64d\uae38\ub3d9"} - 문자열로 인식

# python 객체로 변환
pyObj = json.loads(jsonStr)
print(type(pyObj)) # <class 'dict'>
print(pyObj) # {'id': '1234', 'name': '홍길동'} - key, value로 인식
print(pyObj['name']) # 홍길동


# 3. json file 읽기(decoding)

usagov_bitly.txt
1.52MB

import os
print(os.getcwd()) # C:\3_Pywork-I\workspace
file = open(file="chap07_FileIO/data/usagov_bitly.txt", mode='r', encoding='utf-8')

 

lines = file.readlines() # 줄 단위 전체 읽기

print(type(lines)) # <class 'list'>
print(len(lines)) # 3560
print(lines[:5])
print(type(lines[0])) # <class 'str'>

# list[string] -> dict
rows = [ json.loads(line) for line in lines ]
print(type(rows)) # <class 'list'>
print(len(rows)) # 3560
print(rows[:5])
print(type(rows[0])) # <class 'dict'>
# 타입과 원소의 개수는 같지만 그 안의 형태가 str(문자열)에서 dict로 바뀜

# dict -> DataFrame 변환
# 행렬 구조를 가지게 함으로써 훨씬 가독성 있게 만들 수 있다.
'''
{key:value, key:value, ...} -> {} : row,
'key:value' -> column
'''


import pandas as pd
rows_df = pd.DataFrame(rows)
print(rows_df.info()) # [3560 rows x 18 columns]
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3560 entries, 0 to 3559
Data columns (total 18 columns):
'''

print(rows_df.head())
print(rows_df.tail())


------------------------------------------- example -------------------------------------------

exam01.py
0.00MB
exam02.py
0.00MB
exam03.py
0.00MB

댓글