네이버 부스트캠프 AI Tech 5기 회고-week1 ①

홍찬우·2023년 3월 12일
0

Intro

네이버 부스트캠프 AI Tech 5기를 합격하고, 첫 주를 무사히 보냈다. 한 주 동안 내가 배운 것 중 몰랐거나 중요하다고 생각한 부분 및 느낀 점을 써보려 한다.


Python

1. Python 개요

  • 파이썬은 플랫폼(OS)에 독립적인 인터프리터 언어이다.

컴파일러 언어 : 소스코드를 기계어로 먼저 번역하며 실행 속도가 빠르지만 많은 기억장소가 필요함
인터프리터 언어 : 별도 번역과정 없이 소스 코드를 실행 시점에 해석, 실행속도가 느리지만 메모리가 적게 필요

  • 파이썬은 객체 지향 언어이며 동적 타이핑 언어이다.

동적 타이핑 언어 : 프로그램 실행 시점에 데이터 타입을 결정하는 특징을 가짐

2. Basic Syntax

  • 기본적으로 변수는 메모리 주소를 가지고 있고 변수에 들어가는 값은 메모리 주소에 할당된다.
  • 서로 다른 리스트 a, b에서 b = a를 실행 시 a와 b가 같은 메모리 주소를 가리키게 된다. 따라서 a 값을 변경하면 b 값도 변경된다.
  • 이 때, b = a가 아닌 b = a[:] 로 하면 a 원소 값만 복사함 (copy)
  • 2차원 리스트에선 b = a[:] 과 같은 copy를 해도 원소 값을 바꿀 수 없다. 이 때, deepcopy 메서드 이용해야 한다.

function

  • is 연산은 memory 주소를 비교하고, == 연산은 값을 비교한다.
    -5 ~ 256 사이 값은 같은 메모리 주소(정적 메모리)를 이용해 다른 변수에 할당해도 is 연산 시 True가 나온다.

string

  • 이진수 한 자리는 1bit로 저장되며, 1byte는 8bit로 28 = 256까지 저장 가능하다.
  • r"string" 은 string 내부의 \n과 같은 기호들을 그대로 처리한다.

3. 데이터 구조 & 파이써닉 코드

collections 라이브러리

  • deque : 링크드 리스트의 특성을 지원해 줌
  • extend, extendleft 함수도 지원함
  • deque.rotate(1) : 오른쪽으로 1만큼 회전

  • defaultdict : 기존 딕셔너리는 키 값이 없으면 KeyError가 나지만, defaultdict의 경우 키 값을 만들어 줌
  • defaultdict(함수) 형태로 초기 밸류 값을 만들어 줄 수 있음

pythonic

  • 람다 함수는 (lambda x, y: x + y)(50, 10) 과 같은 형태로 사용 가능

  • iter([1, 2, 3])의 경우 1, 2와 그 다음 엘리먼트의 주소값을 같이 저장하게 됨 (3의 경우 다음 엘리먼트 존재하지 않으므로 엘리먼트만 저장)
  • 이 때 iter 객체에 next 함수를 사용하면 다음 엘리먼트를 반환함

  • generator를 사용하면 메모리를 아낄 수 있음
  • generator는 iterator와 다르게 반복 객체의 모든 원소가 메모리에 할당되지 않고 호출된 원소만 할당됨
  • []대신 ()를 사용해 생성
  • yield 함수는 return과 다르게 호출돼도 함수를 종료하지 않는다. for문 또는 next를 이용해 호출될 때마다 한 개씩 yield 값 반환

  • 가변인자 : asterisk(*)을 이용해 개수가 정해지지 않은 변수를 함수의 파라미터로 사용
  • 가변인자는 함수 내에서 튜플로 사용함
  • 키워드 가변인자: asterisk 두 개 (**)를 사용하면 dict type으로 함수 내에서 사용
  • 함수에 전달할 땐 변수 이름과 값을 같이 전달 (e.g. f(a=1, b=2))
  • 함수에선 파라미터로 키워드 형태로 넣고 그 뒤엔 값 형태로 넣으면 안 됨

  • asterisk가 함수에 넘겨지는 가변인자에 포함되면 언패킹시킴
  • e.g. f(1, *(2,3,4,5)) 형태로 넣으면 f(1,2,3,4,5)와 동일

4-1. OOP

매직 메소드

  • 객체를 그냥 print 하면 메모리 주소값이 나오지만, def __str__(self)를 선언한 후 print 시 함수에서 설정한 출력문이 나옴
  • __add__(self, other)의 경우 other는 자신이 아닌 더해지는 다른 객체를 가리킴

상속

  • class A(B) : A class가 B class를 상속
  • super().__init__ : 부모 클래스에서 생성한 것을 상속받아 사용
  • super().메서드() : 부모 클래스의 메서드 사용

다형성

  • 같은 부모 클래스의 상속을 받은 다른 자식 클래스가 같은 이름 메소드의 내부 로직을 다르게 작성 가능
  • 기능이 비슷하면 함수 이름은 같게 하고 기능에 차이를 조금씩 둠

가시성, 캡슐화

  • self.__item = [] : private 변수, 외부에서 접근 불가능
  • 클래스 밖에서 객체.__item로 불러올 수 없음
@property
def items(self):
  return self.__item
# property decorator를 이용해 private 변수인 item에 접근 
# 이 때 class 밖에서 items 함수를 items()가 아닌 items로 호출한다.

일등함수, 일급객체

  • 변수나 데이터 구조에 할당이 가능한 객체
  • map(f, ex) 처럼 함수 f를 파라미터로 사용 가능

decorator

  • 함수 내 또 다른 함수를 inner function이라 하며, 이 함수를 return으로 반환하는 것을 closure라고 한다.
  • decorator는 비슷한 목적의 다른 파라미터를 요구하는 함수 생성을 가능하게 한다.

4-2. module & project

  • __pycache__: 컴파일 된 파일(기계어로 번역된 파일)
  • Alias(별칭): import 모듈명 as alias
  • package : 하나의 대형 프로젝트를 만드는 코드 묶음 (모듈, 폴더 등으로 구성)
  • 리눅스에선 touch 파일명.py로 py파일 생성
  • __init__.py 파일은 현재 폴더가 패키지임을 나타내줌
    파일 내에 __all__ = [모듈 이름들] 및 from . import 모듈명 내용을 포함시킴
  • 패키지 폴더 자체를 실행(cmd에서 python 폴더명)시키면 __main__.py가 실행됨
  • from .render import * # .render는 상대참조
  • from ..render import * # ..render은 render의 부모 디렉토리로 이동 후 같은 경로의 다른 모듈 임포트 가능

5. Exception & File & Log

  • raise Exception (출력문) : raise 구문을 만나면 코드 종료 후 출력문 출력
  • assert 예외조건 : 예외 조건이 False면 AssertionError 발생 후 코드 종료, True면 실행

File

  • file.readlines() : 개행 기준으로 리스트에 저장
  • read(): 전체 읽어옴
  • readline(): readline을 실행할 때마다 한 줄씩 읽어옴
  • write 모드는 파일을 새로 열게 됨(기존 파일을 불러와도 다 초기화하고 새로운 내용만 write), add는 기존 파일에 추가하는 것
  • shutil.copy : 파일 복사
  • pathlib: path를 객체로 다룸
  • cwd = pathlib.Path.cwd()
    cwd : 파일 주소 가리킴
    cwd.parent : 한 단계 위 디렉토리

  • Pickle: 메모리에 있는 데이터를 저장할 수 있음 (영속화)
  • f = open('list.pickle', 'wb')
    pickle.dump(데이터, f) # 데이터 저장
  • f = open('list.pickle', 'rb')
    pickle.load(f) # 피클 load
  • class도 피클에 저장 가능

로깅

  • logger = logging.getLogger("main") : 로깅 객체 생성
  • logging.basicConfig(level=logging.DEBUG) : 기본 레벨을 디버그로 설정
  • steam_handler = logging.FileHandler(파일명, mode='w')
    logger.addhandler(steam_handler)
    -> 로그를 파일로 기록함

configparser

  • 프로그램 실행 설정을 파일에 저장
  • dict type 형태로 관리
  • example.cfg 파일 형태
  • import configparser 후 cfg = configparser.Configparser().read('example.cfg') 로 객체 생성 후 cfg[키] 형태로 json처럼 사용

argparser

  • 프로그램 실행할 때 세팅 정보 저장
  • 커맨드창에서 --a 형식으로 써서 값들을 넣어줌
    보통 긴 것은 --, 짧은 것은 - 사용
    ex) python arg_sum.py -a 10 -b 10
  • logging.Formatter(메세지 format) 을 지정해서 사용

6. Numpy

ndarray

  • 하나의 데이터 타입만 배열에 넣을 수 있음
  • list는 데이터의 주소값이 저장되는 것이고, ndarray는 데이터 값이 그대로 들어감 (연산이 좋음)
  • is 연산자는 메모리 위치를 비교함
    같은 값을 비교할 때 list는 True, ndarray는 False (-5~256 사이의 값이어도 ndarray에선 주소값이 다름)
  • ndarray [1,4,5,8] 의 shape -> (4, )이며 vector를 표현
    [[1,4,5,8]] -> (1, 4)
  • 1byte = 8bit, float 64(64bit) => 데이터 한 개당 8byte 할당
  • rank=0인 array => scalar, 1 => vector, 2 => matrix , n => tensor
  • shape: (쌓인 개수, 로우 개수, 칼럼 개수)
  • nbytes: 데이터 byte 수를 반환

functions

  • reshape: array shape 크기 변경, 원소 개수 동일
    reshape(-1, n) : n개로 칼럼 개수 정하고 스스로 계산해서 row 개수도 선정한다. (n,-1)도 가능
    reshape된 결과를 변수에 할당해야 변경된 matrix를 사용 가능
  • flatten: 다차원 array를 1차원으로 변환
  • list에선 [i][j]로 인덱싱하지만 ndarray에선 [i, j]로 표기
  • list와 달리 행, 열 부분 나눠서 슬라이싱 가능
    a[1, 1:3] -> 1 row의 1~2 col
  • arange(30) : range(0, 30)으로 vector 생성
    arange(0, 5, 0.5) : step이 0.5 (list에선 불가능)
  • np.empty(shape, dtype) : 메모리 공간을 잡지 않고 빈 값의 ndarray를 생성한다. 메모리 초기화가 안 돼서 빈 값에 다른 값이 들어갈 수 있음
  • np.ones_like(array) : array의 크기만큼 ones matrix 반환 (zeros, empty도 가능)
  • identity(n) : n 크기의 단위 행렬(1 대각 행렬) 생성
  • eye(N, M, k): (N, M) 크기의 행렬에서 k번째부터 단위 행렬로 생성
    k default = 0, 음수 인덱싱도 가능
  • diag(array): array의 대각 행렬 값만 추출해서 vector로 반환 eye처럼 k 사용 가능
  • np.random.uniform(0, 1, 10): [0, 1)의 10 크기만큼 랜덤으로 float 값 array
  • np.random.normal: 정규분포를 따르는 데이터 생성

  • array.sum(): 어레이 총합
    mean, var, std 다 가능
  • matrix에선 axis로 연산 방향 지정 가능 (axis = 0: 열방향, 1 : 축방향)
  • 3order tensor에선 0: 채널 방향, 1: 열방향 , 2 : 축방향
  • vstack(vertical stack): 밑에다 붙임
    hstack(horizontal stack): 옆에다 붙임
    np.vstack(a, b) 형태
  • np.concatenate((a, b) axis = 0) 형태
  • b[np.newaxis, :] : b가 [5, 6]이면 축을 하나 추가해서 [[5,6]]으로 바꿈 (2, ) -> (1, 2)
  • array * array -> 같은 위치 곱 (element-wise operation)
  • array.dot(array) -> 행렬곱(내적)
  • array.transpose() 또는 array.T : 전치
  • matrix + scalar: broadcasting, 행렬 모든 element에 scalar 값만큼 더해줌 (뺄셈, 곱셈, 나눗셈, 몫, 제곱 등 연산 가능)
    matrix + vector(vector를 matrix에 다 더해줌), vector + vector (모두 더하면서 matrix를 생성) 모두 가능
  • 대용량 계산에는 넘파이가 제일 빠름

boolean functions

  • array = [0, 1, 2]일 때,
    array > 1 -> [False, False, True] 반환
    np.any(a > 1) -> 하나라도 True면 True 반환
    np.all(a > 1) -> 모두가 all이면 True 반환
    np.logical_and(a>0, a<3) : 두 bool list 비교 후 and 연산
    np.logical_not(a) : not a
    np.logical_or(b,c) : b, c or연산

  • where 리턴값은 튜플
  • np.where(a > 0, 3, 2) : a > 0은 bool array이고 True 영역에는 3이, False 영역에는 2가 들어감
    np.where(a>5) : 5> 식을 만족하는 index 값 반환
  • np.isnan(a) : 메모리 값이 존재하지 않는지 반환
  • np.isfinite(a) : 메모리 초과하는 값인지 반환(np.Nan이랑 np.Inf에는 False)
  • np.argmax(a) : a array에서 가장 큰 값의 index 반환
    np.argmin(a) : 가장 작은 값
    matrix에 넣으면 axis 방향대로 가장 큰 값들 또는 작은 값들 뽑아낸 벡터로 반환
  • a.argsort() : 가장 작은 값부터 인덱스를 뽑아줌
    a[np.argmax(a)]를 해주면 인덱스가 아닌 최대값 자체를 뽑아냄
  • condition = a>3 # bool array
  • a[condition]: 3보다 큰 값만 포함하는 어레이 반환 (condition에서 True)
    a = [2,4,6,8]
    b = [0,0,1,3,2,1]
    a[b]: [2,2,4,8,6,4] a.take(b)와 같은 결과 # fancy index
    b matrix를 index로 취급
    a[b, c]처럼 matrix 형태도 가능
  • loadtxt, savetxt로 txt파일 불러오고 저장 가능
    np.save : pickle 형태로 데이터 저장 / np.load로 불러오기
    np.save(파일명.npy, arr = 객체) / np.load(file = 파일명.npy)

7. Pandas

groupby

  • df.groupby('team')['points'].sum() : 데이터프레임의 team 칼럼을 기준으로 묶어 point의 총계를 구하며, 시리즈 반환
  • df.groupby(['team', 'year'])['points'].sum() 처럼 두 개의 칼럼으로 그룹핑도 가능
    이 때 인덱스는 두 개이며, 이를 hierarchical index라고 함 (데이터가 한 개고 인덱스가 두 개 이상이어도 시리즈)
  • index를 찍으면 multi index라고 나오며, 멀티인덱스 시리즈에 unstack() 함수를 적용하면 matrix 형태로 풀어줌
    또는 reset_index를 적용하면 multi index를 single index로 변환 ***
  • hierarchical index에 sort_index(level=) 함수를 적용하면 level 파라미터의 인덱스를 기준으로 정렬
  • h_index.sum, std, mean 등 level을 지정해줘서 구할 수 있음

  • grouped = df.groupby('team') 처럼 사용하면 grouped는 튜플을 원소로 가짐
    (그룹 이름, 그룹 데이터(dataframe type) )
    for name, group in grouped의 형태로 사용 가능
  • grouped.get_group(그룹 이름)을 사용하면 특정 그룹의 그룹 데이터를 뽑아낼 수 있음
  • grouped.agg(sum): 그룹별 칼럼 데이터의 총합을 구함 (np.mean, sum, std 등 사용 가능)
  • grouped[칼럼명].agg([sum, mean, std]) 와 같이 그룹 내 특정 칼럼의 여러 통계치를 뽑아낼 수도 있음

  • score = lambda x: (x - x.mean() ) / x.std() # 정규화
    grouped.transform(score)
    transform은 개별 데이터에 score 함수를 적용한다. 따라서 평균, 표준편차가 각 팀마다 구해지고 개별 데이터에 정규화가 적용됨

  • df.groupby('team').filter(lambda x: len(x) > 3) : team으로 그룹핑 했을 때 행이 3개 초과하는 데이터만 추출, dataframe 반환
  • df.['team'].value_counts 를 사용하면 각 팀별 데이터 개수 파악 가능
  • groupby('team', as_index=False)를 하면 team을 인덱스로 쓰지 않음
    reset_index와 같은 기능

merge

  • pd.merge(df1, df2, on='칼럼명') : on 칼럼명 기준으로 같은 값 merge, 공통된 데이터만 추출
  • pd.merge(df1, df2, left_on='칼럼명1', right_on='칼럼명2') : 두 칼럼 이름이 다를 때 따로 지정해줘서 merge
  • pd.merge(df1, df2, on='칼럼명', how = 'left') : left join, 왼쪽엔 있고 오른쪽에 없으면 nan값으로 fill
  • how = 'right'으로 하면 right join, how = 'outer'으로 하면 full join, default는 inner join
    index기준으로 join하려면 merge(right_index = True, left_index = True)
  • merge할 때 칼럼 이름이 동일하면 _x, _y가 붙음. 이 때 한 칼럼은 drop해줘야 함
  • pd.concat([df1, df2], axis = ) 형태로 사용, axis = 0이면 밑으로, 1이면 옆으로 붙임
    axis = 0은 df1.append(df2)와 같은 형태

profile
AI-Kid

0개의 댓글