Naver Boostcamp

[Python] 객체 지향 프로그래밍, Numpy, Pandas

HaneeOh 2023. 3. 7. 11:40

1주차의 내용은 대부분 pre course와 동일하고,

파이썬 문법이나 모듈 등 기초적인 내용이 대부분이라

강의자료로 복습하고 어려운 내용만 영상으로 복습하기로 했다.

 

Python

1. 객체 지향 프로그래밍(Object Oriented Programming)

OOP는 클래스와 인스턴스로 나뉨

 

이름 짓는 법

class명: 띄어쓰기 부분에 대문자

변수명: 띄어쓰기 부분에 "_" 추가

예) 변수 camel_case, 클래스 CamelCase

 

OOP의 특징

상속: 부모 클래스로부터 속성과 Method를 물려 받은 자식 클래스를 생성

def __init__에 super().__init__() 을 삽입한다.

다형성: 같은 이름 메소드의 내부 조직을 다르게 작성

가시성: 객체의 정보를 볼 수 있는 레벨을 조절하는 것

private 변수 self.__(변수명)을 활용

 

decorater

데코레이터 함수에 대상 함수를 매개변수로 전달하여 사용한다. 반환값은 함수의 형태로 반환한다.

여러 번의 데코레이터도 사용이 가능하다.

def star(func):
    def inner(*args,**kwargs):
        print("*" *30)
        func(*args,**kwargs)
        print("*" *30)
    return inner
def percent(func):
    def inner(*args,**kwargs):
        print("%" *30)
        func(*args,**kwargs)
        print("%" *30)
    return inner

@star
@percent
def printer(msg):
    print(msg)

printer("Hello")
******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Hello
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************

print문이 한 번만 실행되는 이유가 처음에는 이해가 안 갔는데,

데코레이터 함수가 여러 번 따로 실행되는 것이 아니라 위에서부터 아래로 데코레이터 함수를 차례로 씌워서 매개변수로 전달하는 과정이었다.

즉 위에서 printer("Hello")는 star(percent(printer("Hello")))와 동일하다.

 

모듈과 프로젝트

모듈: 작은 프로그램 조각들

패키지: 모듈을 모아놓은 단위, 하나의 프로그램

 

2. Python Data Handling

Exceptiong & Log

try ~ except ~ else문법

try:
	예외 발생 가능 코드
except <Exception Type>:
	예외 발생시 대응하는 코드
else:
	예외가 발생하지 않을 때 동작하는 코드

try ~ except ~ else문법

try:
	예외 발생 가능 코드
except <Exception Type>:
	예외 발생시 대응하는 코드
finally:
	예외 발생 여부와 상관없이 실행됨

raise 구문

필요에 따라 강제로 Exception을 발생

raise <Exception Type>

assert 구문

특정 조건을 만족하지 않을 경우 Exception 발생

assert 조건식, 조건식이 False일 때 출력할 메시지

logging 모듈

import logging
logger = logging.getLogger("main") # Logger 선언
stream_hander = logging.StreamHandler() # Logger의 output 방법 선언
logger.addHandler(stream_hander) # Logger의 output 등록

logger.setLevel(logging.DEBUG)
logger.debug("틀렸잖아!")
logger.info("확인해")
logger.warning("조심해!")
logger.error("에러났어!!!")
logger.critical("망했다...")

debug: 개발시 처리 기록을 남겨야하는 로그 정보를 남김

info: 처리가 진행되는 동안의 정보를 알림

warning: 사용자가 잘못 입력한 정보나 의도치 않은 정보가 들어왔을 때 알림

error: 잘못된 처리로 인해 에러가 났으나, 프로그램은 동작할 수 있음을 알림

critical: 잘못된 처리로 데이터 손실이나 더이상 프로그램이 동작할 수 없음을 알림

 

configparser

프로그램의 실행 설정을 file에 저장함

설정파일을 dict type으로 호출 후 사용

#'example.cfg'

[SectionOne]
Status:KSingle
Name:KDerek
Value:KYes
Age:K30
Single:KTrue
[SectionTwo]
FavoriteColor =KGreen
[SectionThree]
FamilyName:KJohnson
import configparser
config = configparser.ConfigParser()
config.sections()
config.read('example.cfg')
config.sections()
for key in config['SectionOne']:
print(key)
config['SectionOne']["status"]

 

argparser

Console 창에서 프로그램 실행시 Setting 정보를 저장함

def main():
parser =argparse.ArgumentParser(description='PyTorch MNISTExample')
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 ofepochs 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='SGDmomentum (default:0.5)')
parser.add_argument('--no-cuda',action='store_true',default=False,help='disables CUDAtraining')
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()
if __name__=='__main__':
main()

 

Logging formmater

로그에 포맷을 지정할 수 있다

formatter = logging.Formatter('%(asctime)s %(levelname)s %(process)d %(message)s')

 

 

Data Handling

CSV

필드를 쉼표(,)로 구분한 텍스트 파일

엑셀 양식의 데이터를 프로그램에 상관없이 쓰기 위한 데이터 형식

 

Web(HTML)

정규식(Regex)을 활용하여 필요한 데이터를 추출

 

XML

데이터의 구조와 의미를 설명하는 Tag를 사용하여 표시하는 언어

BeautifulSoup을 통해 Scraping

 

JSON

JavaScrip의 객체 표현 방식

데이터 용량이 적고, code로의 전환이 쉬움.

파이썬의 dict type과 상호 호환 가능

 

3. Libraries

Numpy

Numerical Python의 약자

파이썬의 고성능 과학 계산용 패키지

반복문 없이 데이터 배열에 대한 처리를 지원함

 

호출 방법

import numpy as np

 

배열 생성

arr = np.array([1, 3, 5, 6], float)

data type에 따라 각 element가 차지하는 memory의 크기가 결정됨

 

shape과 type 확인

print(arr.shape)
print(arr.dtype)

array의 rank에 따라 불리는 이름이 있다.

Rank Name Example
0 scalar 7
1 vector [10,10]
2 matrix [[10,10],[15,15]]
3 3-tensor [[[1,5,9],[2,6,10]],[[3,7,11],[4,8,12]]]

 

reshape

array의 shape을 변경함. element의 개수는 동일

test_matrix = [[1,2,3,4], [1,2,5,8]]
print(np.array(test_matrix).shape) # (2,4)
print(np.array(test_matrix).reshape(8,).shape) # (8,)

-1의 의미: size를 기반으로 남는 차원으로 부터 추정

print(np.array(test_matrix.reshape(2,4).shape)) # (2, 4)
print(np.array(test.matrix.reshape(-1,2).shape)) # (4, 2)

 

flatten

다차원 array를 1차원 array로 변환

test_matrix = [[[1,2,3,4], [1,2,5,8]], [[1,2,3,4], [1,2,5,8]]]
print(np.array(test_matrix).flatten())

 

indexing

list와 달리 이차원 배열에서 [0, 0] 표기법을 제공

a = np.array([[1,2],[3,4]], int)

print(a[0, 0]) # 1
print(a[0][0] # 2

 

creation function

arange: array의 범위를 지정하여 값의 리스트를 생성하는 명령어

# integer로 0부터 29까지 배열 추출
np.arange(30)

# np.arange(시작, 끝, step)
np.arange(0, 5, 0.5)

zeros: 0으로 가득찬 ndarray 생성

np.zeros(shape=(10,), dtype=np.int8)

ones: 1로 가득찬 ndarray 생성

np.ones(shape=(10,), dtype=np.int8)

empty: shape만 주어지고 비어있는 ndarray 생성

np.empty(shape=(10,), dtype=np.int8)

ones_like: 기존 ndarray의 shape 크기 만큼 1, 0 또는 empty array를 반환

test_matrix = np.arange(30).reshape(5,6)
np.ones_like(test_matrix)

identity: 단위행렬을 생성함

np.identity(3)

eye: 대각선이 1인 행렬, k값의 시작 index 변경 가능

np.eye(2)
# array([[1., 0.],
		 [0., 1.]]

np.eye(2, 2, k=2)
# array([[0., 1.],
		  0., 0.]]

diag: 대각 행렬의 값을 추출함

matrix = np.arange(9).reshape(3, 3)
np.diag(matrix) # array([0, 4, 8])

random sampling

np.random.uniform(0, 1, 10) # 0부터 1까지 실수 중에서 균등분포로부터 무작위 10개 추출
np.random.normal(0, 1, 10) # 0부터 1까지 실수 중에서 정규분포로부터 무작위 10개 추출

 

operation function

concatenate: numpy array를 합치는 함수

a = np.array([[1,2,3]])
b = np.array([[2,3,4]])
np.concatenate((a,b), axis=0)
# array([[1,2,3],
		 [2,3,4]])

element-wise operations: array간 shape이 같을 때 일어나는 연산

matrix_a * matrix_b

dot product: matrix의 기본 연산

matrix_a.dot(matrix_b)

 

numpy performance

timeit: jupyter 환경에서 코드의 퍼포먼스를 체크하는 함수

def scalar_vector_product(scalar, vector):
    result = []
    for value in vector:
        result.append(scalar * value)
    return result

iteration_max = 100000000
vector = list(range(iteration_max))
scalar = 2

%timeit scalar_vector_product(scalar, vector) # for loop을 이용한 성능
%timeit [scalar * value for value in range(iteration_max)] # list comprehension을 이용한 성능
%timeit np.arange(iteration_max) * scalar # numpy를 이용한 성능

Other functions

all: array의 데이터 전부가 조건에 만족 여부 반환

any: array의 데이터 일부가 조건에 만족 여부 반환

a = np.arange(10)
np.any(a>5), np.any(a<0) # (True, False)
np.all(a>5), np.all(a<10) # (False, True)

np.where: 조건에 만족하는 index 반환

a = np.arange(10)
np.where(a>5)
# array([6,7,8,9]),)

a = np.array([1, 3, 0], float)
np.where(a > 0, 3, 2) # where(condition, Talse일 경우 값, False일 경우 값)
# array([3, 3, 2])

 

np.isnan: Nan 값인지 체크하여 여부 반환

np.isfinite: 유한한 값인지 체크하여 여부 반환

np.argmax: array 내 최대값의 index 반환

np.argmin: array 내 최소값의 index 반환

 

fancy index

numpy는 array를 index value로 사용해서 값 추출

matrix 형태의 데이터도 가능

a = np.array([[1, 4], [9, 16]], float)
b = np.array([0, 0, 1, 1, 0], int)
c = np.array([0, 1, 1, 1, 1], int)
a[b, c]
# array([1., 4., 16., 16., 4.])

b와 c의 array 값을 각각 행과 열로 하여 인덱싱

 

Pandas

호출

import pandas as pd

pandas의 구성

Series: DataFrame 중 하나의 Column에 해당하는 데이터의 모음 object

DataFrame: DataTable 전체를 포함하는 Object

 

dataframe은 series를 모아서 만든 data table로 기본 2차원이다.

 

dataframe indexing

loc은 index 이름, iloc은 index 번호를 통해 인덱싱을 한다.

loc은 3이라는 이름의 인덱스까지 추출이 된 것을 확인할 수 있고,

iloc은 3번째 인덱스인 47까지 추출된 것을 확인할 수 있다.

 

drop

index 번호에 해당하는 행을 drop한다.

axis = 1 지정으로 열을 기준으로 drop 할 수있다.

 

map, lambda, apply

map은 반복 가능한 객체를 반복문 없이 일괄적으로 처리하고 싶을 때 사용한다.

반환값이 map 객체이기 때문에 다시 list나 tuple화 하여 사용해야 함.

>>> a = [1.2, 2.5, 3.7, 4.6]
>>> a = list(map(int, a))
>>> a
[1, 2, 3, 4]

pandas의 series type의 데이터에도 map 함수를 사용할 수 있다.

dict type을 통해 map을 적용하면 key에 해당되는 값은 value로 교체해준다.

df["sex_code"] = df.sex.map({"male":0, "female":1})

dict type을 활용하여 sex가 male인 데이터는 0, sex가 female인 데이터는 1의 값을 가지는 칼럼을 생성하였다.

 

apply는 map과 달리 series 전체 column에 함수를 적용한다.

f = lambda x: x.max() - x.min()
df.apply(f)

applymap은 column이 아닌 row 단위로 함수를 적용한다.

 

f = lambda x:  -x
df.applymap(f).head()

groupby

groupby는 다른 연산 함수와 함께 사용해야 한다.

aggregation: 연산 함수를 여러 개 활용한 결과 데이터를 추출해줌

transformation: 해당 정보를 변환해줌

filteration: 특정 정보를 제거하여 보여주는 필터링 기능

 

merge

두 개의 데이터프레임을 하나로 합치는 기능

칼럼을 지정하여 해당 칼럼 데이터를 기준으로 합치게 된다.

두 데이터프레임의 칼럼명이 다를 경우 left_on과 right_on을 통해 지정할 수 있다.

 

concat

key값 없이 두 데이터를 붙이고 싶다면 concat을 활용하자.

axis를 통해 가로로 붙일지 세로로 붙일지 정할 수 있다.