부트캠프 정리

[멋쟁이사자처럼부트캠프 데이터분석 2주차]-파이썬 모듈/데이터분석 기초

지니248 2025. 7. 25. 13:01
Python의 내장 모듈 사용법과 예외 처리 방법을 학습하였습니다. 
또한, Numpy와 Pandas를 통해 데이터 분석의 기본적인 방법도 함께 익혔습니다.
⚠️본 글은 부트캠프 수업 내용을 기반으로 한 개인 학습 기록입니다.

Python 모듈

1. 모듈이란?

  • 여러 변수와 함수를 가지고 있는 파이썬 파일
  • 코드의 재사용성을 높임
  • 프로그램 체계적 구성
  • 협업 시 역할 분담 가능

2. 주요 내장 모듈

  • 수학 관련 모듈
    • import math
    • pi: 3.141592...
    • sqrt: 루트
    • floor: 내림
    • ceil: 올림
import math

math.pi              # 3.141592653589793
math.sqrt(25)        # 5.0
math.ceil(4.3)       # 5
math.floor(3.7)      # 3

 

  • 랜덤모듈
    • import random
    • randint: 랜덤 정수
    • choice: 랜덤 선택
    • shuffle: 순서 섞기
import random

random.randint(1, 20)  #1~20 사이의 정수 중 하나를 무작위로 반환

fruit = ["딸기" , "수박", "복숭아", "참외"]
random.choice(fruit)   #fruit 리스트에서 무작위로 하나 선택하여 반환
random.shuffle(fruit)  #fruit 리스트의 요소들을 무작위로 섞음(리스트 자체 변경)

 

  • 날짜와 시간 모듈
    • import datetime
    • 현재 날짜와  시간 구할 수 있음
    • 특정 날짜 생성 가능
    • 날짜 간의 차이 계산 가능 ➡️ 시, 분, 초 모두 같아야 함
import datetime
now =  datetime.datetime.now()  #현재 시간 구하기
print(now)

 

  • 시스템 모듈
    • import sys
      • 파이썬 버전 확인
      • 명령행 인수 접근
      • 프로그램 종료
      • 모듈 경로 확인
    • import os
      • os.getenv("이름", "기본값"): 환경변수를 읽고, 없으면 기본값 반환
import sys
import os

print(f"파이썬 버전: {sys.version}")
print(f"현재  디렉터리 위치: {os.getcwd()}")
print(f"사용자 이름: {os.getenv('USER', '알 수 없음')}")

3. 모듈 가져오는 방법

  • import: 모듈 전체 가져오기
  • from: 필요한 것만 가져오기
  • 모든 것 가져오기 ➡️ 권장 x
  • as: 별칭 사용하기
#모듈 전체 가져오기
import math

#필요한 것만 가져오기
from math import sqrt, pi

#모든 것 가져오기
from math import *

#별칭 사용하기
import math as m

 Python 구문오류/예외

1. 구문오류 (Syntax Error)

  • 프로그램 실행 전에 발생
  • 문법 규칙을 위반
  • 코드 직접 수정

2. 예외 (Exception)

  • 프로그램 실행 중에 발생
  • 예상치 못한 상황 발생
  • 예외처리로 대응 가능
#try-except 구조
try:
    #예외가 발생할 수 있는 코드
except:
    #예외가 발생했을 때 실행할 코드
    
#try-except-else 구문
try:
    #예외가 발생할 수 있는 코드
except:
    #예외가 발생했을 때 실행할 코드
else:
    #정상일 때 실행
    
#try-except-finally 구문
try:
    #예외가 발생할 수 있는 코드
except:
    #예외 발생 시 실행할 코드
finally:
    #예외 발생 여부와 관계없이 항상 실행
student_scores = [85, 92, 78]
try:
    print(student_scores[5])   #존재하지 않는 인덱스이므로 IndexError발생
except IndexError:
    print("리스트 범위를 벗어났습니다")   #예외 발생 시 실행
finally:
    print("프로그램을 종료합니다")   #예외 발생 여부와 관게 없이 무조건 실행

# 출력 결과:
리스트 범위를 벗어났습니다
프로그램을 종료합니다
def divide_numbers(a, b):
    try:
        result = a/b
        return result
    except ZeroDivisionError:    #ZeroDivisionError: 0으로 나누기를 시도할 때 발생하는 오류
        return "0으로 나눌 수 없음"
    finally:
        #return이 있어도 finally가 먼저 실행되고, 그 뒤에 값이 반환됨
        print("함수 종료")

# 출력 결과:
함수 종료
5.0
함수 종료
0으로 나눌 수 없음

Numpy

1. Numpy 개념

📌NumPy의 핵심 데이터 구조인 `ndarray`는 다차원 배열 객체이다

  • C언어로 구현된 고성능 수치 계산 라이브러리
  • 다차원 배열(ndarray)를 기반으로 빠른 연산 가능
  • 반복문 없이 벡터화 연산 지원
  • 데이터 분석, 시각화, 머신러닝, 이미지 처리, 금융 공학 등에 사용됨

2. 배열의 속성

  • ndim: 차원의 수
  • shape: 차원의 크기(모양)을 튜플로 표현
  • size: 총 원소의 개수
  • dtype: 데이터 타입
  • itemsize: 메모리 크기 (bytes)
  • nbytes: 전체 메모리 크기 (메모리 사용량)
  • axis: 배열의 축
    • axis = 0: (Column)
    • axis = 1: (Row)
import numpy as np

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

print(a.ndim)     # 2 → 2차원 배열
print(a.shape)    # (2, 3) → 2행 3열
print(a.size)     # 6 → 총 원소 개수
print(a.dtype)    # int64 (또는 int32)
print(a.itemsize) # 각 요소가 차지하는 바이트 수 (예: 8)
print(a.nbytes)   # 전체 배열의 메모리 사용량 = size * itemsize

# axis 예시
print(np.sum(a, axis=0))    # [5 7 9] → 열 기준 합 (세로 방향)
print(np.mean(a, axis=1))   # [2.0 5.0] → 행 기준 평균 (가로 방향)

3. 뷰(View)/복사(Copy)

    • 원본 배열의 메모리 공유
    • 수정하면 원본도 함께 변경
    • 얕은 복사 (Shallow Copy)
    • 배열을 슬라이싱 할 때(:) 사용
    • 형태만 바꿀 때(reshape, transpose) 사용
    • arr.view(): 새로운 view 생성 메서드
  • 복사
    • 완전히 독립된 배열
    • 수정해도 원본은 변경되지 않음
    • 깊은 복사 (Deep Copy)
    • 다른 배열과 산술 연산을 수행할 때 사용
    • arr.copy(): 복사본을 생성하는 메서드
import numpy as np

# 원본 배열 생성
arr = np.array([1, 2, 3, 4, 5])

# 뷰: 메모리를 공유함
view_arr = arr[1:4]       # 슬라이싱 → 얕은 복사
view_arr[0] = 10

print("원본:", arr)        # [1 10 3 4 5]
print("뷰:", view_arr)     # [10 3 4]

# 복사: 메모리를 공유하지 않음
copy_arr = arr.copy()
copy_arr[0] = -1

print("원본:", arr)        # [1 10 3 4 5]
print("복사본:", copy_arr)  # [-1 10 3 4 5]

4. 배열 생성 방법

  • np.array와 np.asarray
    • np.array(): 항상 새로운 배열을 복사하여 만든다
    • np.asarray(): 복사하지 않고 기존 데이터를 그대로 배열로 변환 ➡️ 메모리 사용 더 효율적 (필요할 때만 복사)
  • zeros(shape): 모든 원소가 0인 배열 생성
  • ones(shape): 모든 원소가 1인 배열 생성
  • full(shape, full_value): 지정 값(full_valeu)으로 모든 원소를 채운 배열 생성
  • _like: 기존 배열의 모양과 데이터 타입 복제 ➡️ 새로운 배열이 만들어짐
  • arange: 정수 뿐만 아니라 실수 간격 지정
    • np.arrange(start, stop, step)
  • linspace: 시작점과 끝점 사이 원하는 개수만큼 균일한 간격으로 나눈다
    • np.linspace(start, stop, num)
import numpy as np

# np.array 와 np.asarray
lst = [1, 2, 3]
arr1 = np.array(lst)
arr2 = np.asarray(lst)
lst[0] = 100
print(arr1)  # [1 2 3] → 복사됨, 원본 변경 안 따라감
print(arr2)  # [100 2 3] → 참조됨, 원본 변경 따라감

# 기본 배열
canvas = np.zeros((3, 4))   # 모든 값을 0으로 초기화
print(f"0으로 채워진 3x4 캔버스 배열:\n{canvas}") 

mask = np.ones((2, 5), dtype=int)   # 모든 값을 1로 초기화
print(f"1로 채워진 2x5 정수 배열 :\n{mask}")

default_stock = np.full((5,5), 100)
print(f"100으로 채워진 5x5 재고 배열:\n{default_stock}")

# _like
sales_data = np.array([[120, 130], [140, 150]])
buget_data = np.full_like(sales_data, 100)  # 원본과 똑같은 모양의 예산 배열을 100으로 채우기
print(f"매출 데이터와 같은 모양의 예산 배열:\n{buget_data}") 

# arange
print(np.arange(1, 5))        # [1 2 3 4]
print(np.arange(0, 1, 0.2))   # [0.  0.2 0.4 0.6 0.8] -> 0부터 1 전까지 0.2 간격의 실수 배열

# linspace
print(np.linspace(0, 1, 5))   # [0.   0.25 0.5  0.75 1.]

5. 무작위 배열

  • seed(숫자): 생성되는 난수들이 항상 동일하게 나옴 (난수 고정)
  • rand: 0과 1사이 균등 분포에서 무작위 실수 추출
  • randn: 표준 정규분포(평균 0, 표준편차 1)에서 무작위 실수 추출
  • randint: low와 high 사이의 정수 무작위로 추출
    • randint(low, high, size)
  • choice: 배열(a)에서 무작위로 값 추출, p는 확률
    • choice(a, size=None, replace=True, p=None)
      • size : 뽑을 개수
      • replace : 중복 허용 여부(True/False)
      • p : 확률 분포(합이 1이어야 함)
  • shuffle(arr): 배열 arr의 순서를 무작위로 섞음 (원본 배열 변경)
  • dot(a, b): 두 배열의 내적 (행렬 곱)
  • normal: 일반 정규분포, 평균과 표준편차 조절 가능
    • normal(loc, scale, size)
      • loc : 평균
      • scale : 표준편차
import numpy as np

# seed
np.random.seed(42)  # 랜덤 고정 (항상 같은 결과)

# rand
print(np.random.rand(3))       # 실수 3개 생성
print(np.random.rand(2, 3))    # 2행 3열: 0~1 사이 실수 추출

# randn
print(np.random.randn(2, 2))   # 평균 0, 표준편차 1인 정규분포에서 실수 추출 (2행 2열)

# randint
print(np.random.randint(1, 10, size=(2, 3)))  # 1 이상 10 미만 정수 2행 3열 추출

# choice
print(np.random.choice([1, 2, 3], size=5, replace=True, p=[0.1, 0.3, 0.6]))  
# [1, 2, 3] 중 확률 p대로 중복 허용하여 5개 추출

# shuffle
arr = np.array([1, 2, 3, 4, 5])
np.random.shuffle(arr)
print(arr)  # 원본 배열 순서가 무작위로 변경됨

# dot
a = np.array([[1, 2], [3, 4]])
b = np.array([[2, 0], [1, 2]])
print(np.dot(a, b))  # 행렬 곱: (2x2) · (2x2)

# normal
print(np.random.normal(loc=100, scale=10, size=5))  # 평균 100, 표준편차 10인 정규분포에서 실수 5개 생성

6. 브로드캐스팅 (Broadcasting)

📌 Numpy에서 서로 다른 모양 (shape)의 배열 간 연산을 자동으로 처리해 주는 기능

  • 브로드캐스팅 규칙
    • 뒤에서부터 차원을 비교한다
    • 각 차원이 같거나, 하나가 1이면 가능하다
a = np.array([1,2,3])        #shape: (3,), 1차원, 가로/세로 개념 없음, 요소가 3개
a = np.array([[1,2,3]])      #shape: (1,3), 2차원, 1행 3열(가로벡터)
a = np.array([[1],[2],[3]])  #shape: (3,1), 2차원, 3행 1열(세로벡터)
# 브로드캐스팅 가능한 예시
a = np.array([[1, 2, 3],
              [4, 5, 6]])   # shape: (2, 3)
b = np.array([10, 20, 30])  # shape: (3,) → 자동으로 (1, 3)으로 간주 → 뒤에서부터 3이 같으므로 가능

print(a + b)

# 출력 결과
"""
[[11 22 33]
 [14 25 36]]
"""


# 브로드캐스팅 불가능 예시
a = np.array([[1,2,3], [4,5,6]])  #shape: (2,3)
b = np.array([10,20])              #shape: (2,) → 자동으로 (2,1)또는 (1,2)로 변환해도 3과 2가 맞지 않아 불가능

print(a+b) #브로드캐스팅 불가능 → 오류발생

7. 유니버설 함수

  • np.add(a,b): 덧셈
  • np.subtract(a,b): 뺄셈
  • np.multiply(a,b): 곱셈
  • np.divide(a,b): 나눗셈
  • np.power(a,b): a의 b 제곱
  • np.sqrt(a): 제곱근
  • np.exp(a): 로그 밑 e의 거듭제곱
  • np.log(a): 로그
  • np.abs(a): 절댓값

8. 집계 함수

  • np.sum(): 합계
  • np.mean(): 평균
  • np.std(): 표준편차
  • np.var(): 분산
  • np.min(): 최대값
  • np.max(): 최소값

9. 인덱싱/슬라이싱

  • 인덱싱 [ ]: 특정 위치의 단일 원소 선택
  • 슬라이싱 [start:stop:step]: 특정 범위의 원소들을 선택
    • [:] ➡️ 모든원소 선택
    • [::-1] ➡️ 모든 데이터 거꾸로
  • 불리언 인덱싱 [조건]: 조건을 만족하는 모든 원소 선택
  • 팬시 인덱싱 [배열]: 지정된 여러 위치의 원소들 선택
import numpy as np

a = np.array([10, 20, 30, 40, 50])

# 인덱싱
print(a[1])             # 20

# 슬라이싱
print(a[1:4])          # [20 30 40]
print(a[:])               # [10 20 30 40 50]
print(a[::-1])         # [50 40 30 20 10]

# 불리언 인덱싱
print(a[a > 15])     # [20 30 40 50]

# 팬시 인덱싱
print(a[[0, 2, 4]])  # [10 30 50]
print(a[[1, 3]])       # [20 40]

Pandas

📌Python에서 표 형태의 데이터를 다루기 위한 라이브러리

1. 주요 자료 구조

  • Series: 1차원 배열 (인덱스 + 값)
  • DataFrame: 2차원 표 (행 + 열 + 인덱스)
# Series
s = pd.Series([10, 20, 30, 40], index = ['1', '2', '3', '4'])
s

# DataFrame
df = pd.DataFrame({
    'index' : [1, 2, 3, 4, 5],
    'value' : [10, 20, 30, 40, 50]
})
df

2. 수학 연산 메서드

  • add(): 덧셈
  • sub(): 뺄셈
  • mul(): 곱셈
  • div(): 나눗셈
  • mod(): 나머지
  • pow(): 거듭제곱
  • dot(): 행렬곱 (벡터/행렬 내적 연산)
import pandas as pd

df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [10, 20], 'B': [30, 40]})

df1.add(df2)   # 덧셈
df1.sub(df2)   # 뺄셈
df1.mul(df2)   # 곱셈
df1.div(df2)   # 나눗셈
df1.mod(df2)   # 나머지
df1.pow(df2)   # 거듭제곱

⭐ 추가 정리 

1. loc, iloc

📌 DataFrame에서 원하는 행이나 열의 값을 선택할 때 사용

  • loc[ ]​ : 레이블 기반 인덱싱 (행/열 이름으로 접근)
    • df.loc[0, 'A'] #0번째 행의 'A'열
  • iloc[ ] : 정수 위치 기반 인덱싱 (숫자 인덱스로 접근)
    • df.iloc[0, 1] #0번째 행, 1번째 열

2. 정렬 방법

  • Python 기본 리스트
    • list.reverse() : 리스트 자체를 뒤집음 (내림차순 x)
    • reverse=False : 오름차순
    • reverse=True : 내림차순
  • Numpy
    • np.sort() : 오름차순
    • np.sort()[::-1] : 내림차순
  • Pandas
    • ascending=True : 오름차순
    • ascending=False : 내림차순

3. 빅데이터와 엑셀의 차이

  • 엑셀 : 셀 하나하나가 독립된 데이터
  • 빅데이터 : 열(column) 단위로 데이터를 다룸