카카오클라우드 AIaaS 교육/AIaaS를 위한 머신러닝&AI

[스나이퍼팩토리] AIaaS 마스터 클래스 9주차 DAY 43 - numpy,pandas

mangji2 2025. 5. 26. 17:49

[1] 수업 복습 - numpy,pandas 

1) NumPy – 수치 계산의 핵심 도구

🔹 NumPy란?

  • Numerical Python의 줄임말
  • 빠른 과학/수치 연산을 위한 핵심 라이브러리
  • C로 구현된 내부 구조로 성능이 매우 뛰어남
  • Python 리스트보다 메모리 효율이 뛰어나고, 동일한 데이터 타입만 저장 가능

🔹 주요 특징

  • 다차원 배열 객체(ndarray) 지원
  • 벡터화 연산: 전체 배열에 대해 반복문 없이 연산 가능
  • 브로드캐스팅(Broadcasting): 다른 크기의 배열 간 연산 허용
  • 조건식 필터링과 불리언 인덱싱: 조건에 맞는 값 추출 및 할당 용이
  • 행렬 곱(dot) vs 요소별 곱(*): 수학적 의미 차이 존재

🔹 활용 분야

  • 데이터 분석
  • 머신러닝 전처리
  • 이미지 처리
  • 시뮬레이션 등 과학 계산 전반

🔹numpy ndarray 기초

numpy 배열 기초 예제들을 작성해 보겠다.

import numpy as np
# 1차원 배열
arr1 = np.array([1,2,3,4,5])

#2차원 배열 (행렬)
arr2 = np.array([1,2,3],[4,5,6])
# 0으로 채워진 배열
zeros = np.zeros((3,4)) 
# 1로 채워진 배열
ones = np.ones((2,3))
#특정 범위의 균일한 간격 배열
range_arr = np.arange(0,10,2)
#선형 간격 배열
linear_space = np.linspace(0,1,5)
#랜덤 배열
random_arr = np.random.random((2,2))
#주요 속성
arr.shape //(2,3) : 행,열
arr.size // 총 요소 개수
arr.dtype

 

🔹Numpy 통계 함수

import numpy as np

arr = np.array([1,2,3,4,5])
#합계
np.sum(arr)
or
arr.sum()
#평균
np.mean(arr)
#최소값
np.min(arr)
#최대값
np.max(arr)

 

🔹Numpy 브로드캐스팅

다른 크기의 배열 간에 연산을 수행할 때 자동으로 크기를 맞추는 기능

배열의 차원 수가 다를 경우, 작은 차원의 배열이 더 큰 차원으로 확장한다. 특정 차원의 크기가 1인 경우에는 해당 차원은 다른 배열의 크기에 맞게 확장

import numpy as np

# 형태가 다른 배열 연산 
a = np.array([[1, 2, 3], [4, 5, 6]])  # 2x3 배열
b = np.array([[10], [20]])           # 2x1 배열

print(a + b)
# 출력:
# [[11 12 13]
#  [24 25 26]]

 

🔹Numpy 배열 합치기

axis = 0 : 행 합치기 == vstack

axis = 1 : 열 합치기 == hstack

import numpy as np

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

# 세로 방향으로 합치기 (행 추가)
vertical = np.concatenate([a, b], axis=0)
print("세로 합치기 (axis=0):")
print(vertical)
# [[1 2]
#  [3 4]
#  [5 6]
#  [7 8]]

# 가로 방향으로 합치기 (열 추가)
horizontal = np.concatenate([a, b], axis=1)
print("\n가로 합치기 (axis=1):")
print(horizontal)
# [[1 2 5 6]
#  [3 4 7 8]]

# vstack / hstack 함수 사용
v_stack = np.vstack([a, b])  # vertical stack (axis=0)
h_stack = np.hstack([a, b])  # horizontal stack (axis=1)

print("\nvstack (동일한 기능):")
print(v_stack)

print("\nhstack (동일한 기능):")
print(h_stack)

 

🔹Numpy 배열 분할

import numpy as np

# 배열 생성
arr = np.arange(12).reshape(3, 4)
print(arr)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

# 수평 분할 (행 기준)
h_split = np.split(arr, 3, axis=0)  # 3개 배열로 분할
for i, split_arr in enumerate(h_split):
    print(f"분할 {i}:", split_arr)
# 분할 0: [[0 1 2 3]]
# 분할 1: [[4 5 6 7]]
# 분할 2: [[ 8  9 10 11]]

# 수직 분할 (열 기준)
v_split = np.split(arr, 2, axis=1)  # 2개 배열로 분할
for i, split_arr in enumerate(v_split):
    print(f"분할 {i}:", split_arr)
# 분할 0: [[0 1]
#         [4 5]
#         [8 9]]
# 분할 1: [[ 2  3]
#         [ 6  7]
#         [10 11]]

 

🔹Numpy 응용 - 데이터 필터링

import numpy as np

# 샘플 데이터: 고객 나이
ages = np.array([23, 18, 45, 61, 17, 34, 57, 28, 15, 42])

# 성인(18세 이상) 필터링
adult_filter = ages >= 18
print(adult_filter)
# [ True  True  True  True False  True  True  True False  True]

# 성인만 선택
adults = ages[adult_filter]
print(adults)
# [23 18 45 61 34 57 28 42]

# 조건부 필터링 (한 줄로 작성)
young_adults = ages[(ages >= 18) & (ages < 30)]
print(young_adults)
# [23 18 28]


# 상황별 값 할당 (조건부 변경)
ticket_prices = np.zeros_like(ages)  # 같은 크기의 0으로 채워진 배열 생성

# 나이에 따른 티켓 가격 할당
ticket_prices[ages < 18] = 5              # 18세 미만: $5
ticket_prices[(ages >= 18) & (ages < 60)] = 10  # 18-59세: $10
ticket_prices[ages >= 60] = 8             # 60세 이상: $8

print(ticket_prices)
# [10 10 10  8  5 10 10 10  5 10]

 

🔹Quiz 1

다음 코드 실행 결과는?

import numpy as np

arr1 = np.array([1,2,3,4])
arr2 = np.array([5,6,7,8])
result = arr1 * 2 + arr2 // 2
print(result)

#답
#[7,10,13,16]

 

🔹Quiz 2

다음 코드 실행 결과는?

arr = np.array([[1,2,3,4],
				[5,6,7,8],
                [9,10,11,12]])
result = arr[1:, 1::2]
print(result)

답:
#[[6,8]
#  [10,12]]

2) Pandas – 구조화된 데이터

🔹 Pandas란?

  • 표(테이블) 형태의 데이터를 효율적으로 다루는 라이브러리
  • NumPy 기반으로, 빠르고 효율적인 연산 가능
  • Excel + SQL 느낌: 직관적이고 강력한 조작 기능 제공

🔹 핵심 자료구조

  1. Series
    • 1차원 배열
    • 인덱스를 통해 키-값 방식의 데이터 표현
  2. DataFrame
    • 2차원 테이블 구조 (행 + 열)
    • 다양한 데이터 타입 가능 (숫자, 문자, 날짜 등)

🔹 주요 기능

  • 정렬, 필터링, 그룹화, 집계, 조인 등 SQL 같은 기능 가능
  • 결측치 처리, 파생변수 생성, 범주형 요약, 시계열 분석 지원
  • GroupBy: SQL의 GROUP BY와 유사하게 집계 처리
  • 통계 분석: 평균, 표준편차, 상관계수, 공분산 등 계산 가능
  • 데이터 결합(Merge/Join), 행/열 추가(concat)도 간단

🔹 사용 예

  • 고객 분석 (성별, 나이, 지역별 구매 통계)
  • 시간 기반 금융 분석 (월별 수입/지출)
  • 설문조사 응답 집계, 피벗 테이블 분석 등

🔹 DataFrame 생성 및 메소드

import pandas as pd
df = pd.DataFrame(data)

#기본 속성
df.shape #(행,열)
df.columns #['컬럼','','','']
df.dtypes #각 열의 데이터 타입 출력
#데이터 확인
df.head() #처음 5행 출력
#데이터 수정
df['Age'] = df['Age'] + 1 //모든 나이에 1추가
df['country'] = ['','','','',''] //새 열 추가
df.loc[5] = ['', '' ,  , , , ] //새 행 추가
df.drop('Country',axis=1,inplace=True) //열 삭제
df.drop(5, axis=0,inplace=True) //행 삭제

 

loc vs iloc

loc은 라벨 기반으로 행/열 이름을 기준으로 인덱싱한다.

ex) df.loc['a' : 'b' , 'name']

 

iloc은 index 번호를 기준으로 인덱싱한다.

ex) df.iloc[0:2,0]

 

🔹 DataFrame Groupby

groupby는 sql의 groupby와 유사하게 데이터를 그룹화하고 집계하는 기능이다.

 

🔹 DataFrame 정렬 메소드

import pandas as pd

df = pd.DataFrame({
    'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank'],
    'Score': [85, 92, 78, 96, 88, 73],
    'Attendance': [95, 80, 90, 75, 85, 92]
})

# 점수 기준 상위 3명
print("\n점수 기준 상위 3명:")
print(df.nlargest(3, 'Score'))

# 출석률 기준 하위 2명
print("\n출석률 기준 하위 2명:")
print(df.nsmallest(2, 'Attendance'))

# 여러 열 기준 정렬 (다중 기준)
print("\n점수와 출석률 모두 높은 상위 3명:")
print(df.nlargest(3, ['Score', 'Attendance']))

# 점수 기준 내림차순 정렬
print("\n점수 기준 내림차순 정렬:")
print(df.sort_values('Score', ascending=False))

# 여러 열 기준 정렬 (점수 내림차순, 출석률 오름차순)
print("\n여러 열 기준 정렬 (점수 내림차순, 출석률 오름차순):")
print(df.sort_values(['Score', 'Attendance'], ascending=[False, True]))

 

🔹 데이터 공분산

공분산이란 두 변수가 함께 어떻게 변하는지 측정하는 지표이다.

각 변수가 평균에서 얼마나 떨어져 있는지의 곱의 평균으로 계산한다.

예를 들어 한 변수가 증가할 때 다른 변수도 증가하는 경향을 보이는 두 변수의 데이터 공분산은 양수가 되고,

한 변수가 증가할 때 다른 변수는 감소하는 경향을 보이는 두 변수의 데이터 공분산은 음수로 계산된다. 또한, 두 변수 사이에 선형 관계가 약하면 0에 가깝게 나타난다. 

 

이 지표는 값의 크기가 원래 데이터의 단위에 의존하므로 해석이 어렵다는 단점이 있다.

🔹 데이터 상관관계

상관관계란 두 변수 간의 선형 관계 강도를 -1부터 1사이의 값으로 표준화한 지표이다.

1에 가까울수록 강한 양의 상관관계로 표현되고, 0에 가까울수록 선형 관계가 약하다는 것을 나타내고 -1에 가까울수록 강한 음의 상관관계로 나타난다.

 

#상관관계 및 공분산
import pandas as pd

df = pd.DataFrame({
    'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank'],
    'Score': [85, 92, 78, 96, 88, 73],
    'Attendance': [95, 80, 90, 75, 85, 92]
})

# 상관관계 분석
print("\n점수와 출석률의 상관관계:")
print(df[['Score', 'Attendance']].corr())

# 공분산 분석
print("\n점수와 출석률의 공분산:")
print(df[['Score', 'Attendance']].cov())

🔹 데이터 병합(Merge)

sql 조인과 유사하다.

inner join은 교집합 병합

left join은 왼쪽 데이터 모두 포함

right join은 오른쪽 데이터 모두 포함

outer join은 양쪽 데이터를 모두 포함하여 병합한다.

 

import pandas as pd

# 예시 데이터프레임
customers = pd.DataFrame({
    'customer_id': [1, 2, 3],
    'name': ['Alice', 'Bob', 'Charlie']
})

orders = pd.DataFrame({
    'order_id': [101, 102, 103],
    'customer_id': [1, 2, 4]
})

# 내부 조인 (Inner Join) - 양쪽 모두에 있는 데이터만
inner_join = pd.merge(customers, orders, on='customer_id')
print("\n내부 조인 (고객+주문):")
print(inner_join)

# 왼쪽 조인 (Left Join) - 왼쪽 데이터프레임의 모든 행 포함
left_join = pd.merge(customers, orders, on='customer_id', how='left')
print("\n왼쪽 조인 (모든 고객, 주문 없으면 NaN):")
print(left_join)

# 오른쪽 조인 (Right Join) - 오른쪽 데이터프레임의 모든 행 포함
right_join = pd.merge(customers, orders, on='customer_id', how='right')
print("\n오른쪽 조인 (모든 주문, 고객 정보 없으면 NaN):")
print(right_join)

# 외부 조인 (Outer Join) - 양쪽 데이터프레임의 모든 행 포함
outer_join = pd.merge(customers, orders, on='customer_id', how='outer')
print("\n외부 조인 (모든 고객 및 주문):")
print(outer_join)

 

🔹 데이터 연결(concat)

import pandas as pd

# 예제 데이터프레임 1, 2 (세로 연결용)
df1 = pd.DataFrame({
    'A': ['A0', 'A1', 'A2'],
    'B': ['B0', 'B1', 'B2']
})

df2 = pd.DataFrame({
    'A': ['A3', 'A4', 'A5'],
    'B': ['B3', 'B4', 'B5']
})

# 세로 방향으로 연결 (행 추가)
result_rows = pd.concat([df1, df2])
print("\n세로 연결 (행 추가):")
print(result_rows)

# 예제 데이터프레임 3 (가로 연결용)
df3 = pd.DataFrame({
    'C': ['C0', 'C1', 'C2'],
    'D': ['D0', 'D1', 'D2']
})

# 가로 방향으로 연결 (열 추가)
result_cols = pd.concat([df1, df3], axis=1)
print("\n가로 연결 (열 추가):")
print(result_cols)

 3) 데이터 전처리 – 분석의 80%를 차지하는 단계

🔹 전처리란?

  • 원시 데이터(Raw Data)를 분석 가능한 형태로 가공하는 작업
  • 데이터 과학 프로젝트의 70~80% 시간을 차지할 정도로 중요하다.

🔹 전처리의 목적

  • 정확성 향상: 결측치나 이상치 제거로 분석 신뢰도 확보
  • 모델 성능 향상: 깨끗한 데이터가 예측 정확도를 높임
  • 자원 효율성: 중복 제거로 메모리와 계산 자원 절약

🔹데이터 처리 주요 작업

  1. 결측치 처리
    • NA/NaN 탐지 및 제거 또는 대체 (평균, 중간값 등)
  2. 이상치 제거
    • 현실 불가능한 값(ex. -10세, 200세 등)을 제거
    • 방법: IQR 방법, Z-Score 방법
      • IQR: Q1 - 1.5×IQR ~ Q3 + 1.5×IQR 벗어난 값 제거
      • Z-Score: 평균에서 ±3 표준편차 초과 값 제거
  3. 중복 제거
    • 완전 중복 / 부분 중복 / 조건부 제거 (ex. 최고 값만 유지 등)
  4. 데이터 타입 정제
    • 문자열로 저장된 숫자/날짜 → 실제 타입으로 변환
  5. 정규화/표준화 (스케일링)
    • 서로 다른 단위의 특성을 동일 기준으로 조정
    • 표준화: 평균 0, 표준편차 1 (StandardScaler)
    • 정규화: 0~1 범위로 조정 (MinMaxScaler)
    • 로버스트 스케일링: 이상치에 강한 방식 (중앙값 & IQR 기반)
    • 로그 변환: 왜도가 큰 양수 데이터에 적용
  6. 범주형/텍스트 데이터 처리
    • 라벨 인코딩 / 원-핫 인코딩 / 텍스트 벡터화 (TF-IDF 등)
  7. 차원 축소 및 특성 선택
    • 중요하지 않은 변수 제거 → 과적합 방지, 속도 향상
  8. 데이터 분할
    • 훈련/검증/테스트 세트로 나누기, 교차검증을 위한 준비

 

🔹 GIGO 원칙

  • Garbage In, Garbage Out: 나쁜 데이터로는 좋은 결과를 얻을 수 없음

 

오늘은 NumPy와 Pandas의 핵심 기능들과 전처리의 방법들을 공부하며, 다양한 실습을 통해 배열 및 데이터프레임 조작 방법과 함께 알고는 있었지만 헷갈렸던 기능들을 익힐 수 있었고, 내일은 본격적으로 전처리 기법들을 더 심화하여 다룰 예정이라 기대된다. 데이터 분석의 시작은 항상 깨끗한 데이터라고 생각하며 전처리의 중요성을 실습을 통해 확실히 체득하고자 한다.

 


본 후기는 [카카오엔터프라이즈x스나이퍼팩토리] 카카오클라우드로 배우는 AIaaS 마스터 클래스 (B-log) 리뷰로 작성 되었습니다.