• 머신러닝
  • 머신러닝 학습
  • 라이브러리
  • Kaggle
  • 데이터 전처리
  • 실습
  • 지도학습
  • 회고

📚  머신러닝의 정의

  • 컴퓨터가 명시적으로 프로그래밍 되지 않아도 데이터를 통해 학습하고, 예측할 수 있도록 하는 기능
  • 대량의 데이터를 알고리즘에 입력하여 학습과정을 통해 모델을 생성하고 예측을 수행

☑️ 머신러닝의 구성요소

데이터셋 

  • 머신러닝은 데이터셋을 통해서 습하며, 일반적으로 데이터셋은 입력/출력 데이터(레이블)로 구성됩니다.
  • 머신러닝의 베이스가 데이터 셋이기 때문에 중요!
  • 입력 데이터(Feature): 정답을 추론하기 위한 정보 데이터
  • 출력 데이터(레이블): 정답을 맞추기 위한 데이터

 

특징(Feature) 

  • 데이터셋에서 모델이 학습할 수 있는 개별 속성
  • 주택가격예측을 예시로 들 경우 주택의 크기, 위치, 방의 개수 등이 Feature에 해당합니다

 

레이블(label)

  • 예측하고자 하는 목표 변수(맞추기 위한 변수 = 정답이 목표 변수다)
  • 지도학습 모델에서는 레이블이 있는 데이터셋을 이용하여 모델을 학습 시킵니다
  •  

 

모델

  • 데이터의 특징으로 부터 정답(레이블)을 예측할 수 있는 지식을 학습할 수 있는 프로그램/함수
  • 입력데이터와 출력 데이터간의 관계를 학습하여 새로운 데이터에 대한 예측 수행
  • 데이터가 있을 때 특징과 규칙을 찾는 알고리즘

 

학습

  • 모델이 데이터를 통해서 패턴을 인식하고, 이를 기반으로 예측을 수행 할 수 있도록 함수 내의 가중치를 조정하는 과정

 

 📚  머신러닝의 학습

데이터 수집 

  • 모델을 학습시키기 위한 필요 데이터 수집

데이터 전처리 

  • 결측값 처리, 이상치 제거, 정규화 등등

Feature 선택 

  • 중요 feature(특징)을 선택하고 불필요한 Feature를 제거하여 학습효율 높임
  • 여러가지 특징을 결합해서 수학적, 알고리즘적 작업을 진행해 성능을 높여주는 중요한 단계

모델 선택 

  • 문제에 적합한 머신러닝 알고리즘을 선택
  • 여러 특징들의 조합으로 시도해보고 성능을 늘리는 단계

모델 훈련

  • 트레이닝 데이터셋을 사용해서 모델을 학습시킴
  • 훈련을 하며 모든 단계에서 추가, 제거 등 많은 시도가 필수적 (무엇을 보고 추가 제거를 하는거지?)

모델 평가

  • 테스트 데이터셋을 사용하여 모델 성능을 평가

모델 배포 

  • 학습된 모델을 실제 환경에 배포하여 예측 수행

☑️ 학습 방법

지도 학습 (Supervised Learning)

레이블이 있는 데이터셋을 이용하여 모델을 학습시키는 방법

  • 회귀(Regression) : 연속적인 값을 예측하는 문제 ex : 주택 가격 예측, 주식 가격예측
  • 분류(Classification) : 이산적인 값을 예측하는 문제 ex : 이메일 스팸 필터링, 이미지 분류

비지도 학습 (Unsupervised Learning)

레이블이 없는 데이터셋을 이용하려 모델을 학습시키는 방법

  • 군집화(Clustering) : 데이터를 유사한 그룹으로 묶는 문제 ex : 고객 세분화, 이미지 세그멘테이션
  • 차원축소 (Dimensionality Reduction) : 고차원 데이터를 저차원으로 변환 ex : PCA, t-SNE

앙상블 학습 (Ensemble Learning)

여러개의 머신러닝 모델을 결합하여 더 나은 성능을 얻는 방법

  • 배깅(Bagging) : 여러 모델을 독립적으로 학습시키고, 예측을 평균내거나 다수결 투표로 최종 예측 ex : 랜덤포레스트
  • 부스팅(Boosting) : 여러 모델을 순차적으로 학습시키고, 이전 모델의 오차를 보완하여 최종 예측을 수행 ex : 그래디언트 부스팅, XGboost
  • 스태킹(Stacking) : 여러 모델을 학습시키고 예측결과를 새로운 데이터로 사용하여 메타 모델을 학습

📚 머신 러닝을 위한 라이브러리 (Scikit-learn)

  • 다양한 머신러닝 알고리즘을 제공하며, 데이터 전처리, 모델 학습, 평가 및 예측을 위한 도구를 포함

설치

conda install scikit-learn
# conda를 사용하여 Scikit-learn 설치


pip install scikit-learn

# pip를 사용하여 Scikit-learn 설치

 

Scikit-learn 주요기능

  • 데이터 전처리: 스케일링, 인코딩, 결측값 처리 등 다양한 데이터 전처리 기능을 제공합니다.
  • 모델 학습: 회귀, 분류, 군집화 등 다양한 머신러닝 알고리즘을 제공합니다.
  • 모델 평가: 교차 검증, 성능 평가 지표 등 모델 평가를 위한 도구를 제공합니다.
  • 모델 예측: 학습된 모델을 사용하여 새로운 데이터에 대한 예측을 수행할 수 있습니다.

☑️  kaggle

📚 캐글이란?

  • 데이터 과학 및 머신러닝 경진대회 플랫폼
  • 데이터 사이언티스트 / 머신러닝 엔지니어들이 다양한 문제를 해결하고 데이터를 분석
  • 모델을 개발하는데 필요한 데이터셋과 도구를 제공

📚 데이터셋 다운 받기

kaggle competitions download -c 데이터셋 이름

# 타이타닉 데이터셋 다운로드

 

unzip 데이터셋 이름.zip

# 다운로드된 파일 압축 해제


☑️  데이터 전처리

📚 데이터 전처리란?

  • 데이터 분석 및 머신러닝 모델링을 위해 데이터를 준비하는 과정
  • 원시 데이터(raw data)는 종종 불완전하거나, 노이즈가 많거나, 형식이 일관되지 않아 직접 모델링에 사용하기 어려움
  • 데이터 전처리는 데이터의 품질을 높이고, 분석 결과의 신뢰성을 확보하기 위한 필수적인 과정

 


☑️ 실습

📚 결측치

1. 제거

# 결측값이 포함된 행 제거
df_dropped_rows = df.dropna()

# 결측값이 포함된 열 제거
df_dropped_cols = df.dropna(axis=1)

 

2. 대체

# 결측값을 0으로 대체

df_filled = df.fillna(0)

# 결측값을 각 열의 평균값으로 대체

df_filled_mean = df.fillna(df.mean())

# 결측값을 각 열의 중간값으로 대체

df_filled_median = df.fillna(df.median())

# 결측값을 각 열의 최빈값으로 대체

df_filled_mode = df.fillna(df.mode().iloc[0])

 

📚 이상치

1. 확인 (IQR)

# 특정 열의 이상치 확인 (IQR 방법)
Q1 = df['column_name'].quantile(0.25)
Q3 = df['column_name'].quantile(0.75)
IQR = Q3 - Q1

# 이상치 범위 설정
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

# 이상치 확인
outliers = df[(df['column_name'] < lower_bound) | (df['column_name'] > upper_bound)]
print(outliers)

 

2. 대체

# 이상치를 평균값으로 대체
mean_value = df['column_name'].mean()
df['column_name'] = df['column_name'].apply(lambda x: mean_value if x < lower_bound or x > upper_bound else x)

 

3. 제거

# 이상치 제거
df_no_outliers = df[(df['column_name'] >= lower_bound) & (df['column_name'] <= upper_bound)]

 

📚 중복 데이터

1. 확인

# 중복된 행 확인
print(df.duplicated().sum())

 

2. 제거
# 중복된 행 제거
df_no_duplicates = df.drop_duplicates()

 

📚 데이터 타입 변환

df['column_name'] = df['column_name'].astype(변환할 타입)

 

📚 인코딩

범주형 데이터 => 더미 변수

df_encoded = pd.get_dummies(df, columns=['category_column'])

 

📚 샘플링

# 데이터셋에서 50% 샘플 추출

df_sampled = df.sample(frac=0.5)

 

# 데이터셋에서 100개의 샘플 추출

df_sampled_n = df.sample(n=100)

 


☑️  지도학습: 회귀모델

📚 지도학습이란?

  • 정답이있고 정답을 데이터를 통해 학습하는 방법을 말한다.

📚 회귀 모델

  • 연속적인(간단한) 값을 예측하는 모델 (키, 가격 등을 예측)

☑️선형회귀

  • 선형회귀는 종속 변수와 하나 이상의 독립 변수 간의 선형 관계를 모델링 하는 방법입니다
  • 독립변수의 수에 따라 단순 선형회귀와 다중 선형회귀로 나뉩니다
  • 독립변수: 예측하기 위해 사용하는 정보
  • 선형관계: 곱셈과 덧셈만으로 이루어진 관계
  • 단순 선형회귀: B1 + B2 * 독립변수
  • 다중 선형회귀 : B1 + B2 * 독립변수1 + B3 * 독립변수2 (독립변수가 여러개 들어가있어서)
  • 가중치 (B1, B2, B3) = 학습(목적함수를 최소화한 B1과 B2를 찾는게 학습이다.)
  • 목적함수(loss function): 예측값과 정답값 사이의 차이를 수치로 나타내는 것(값이 줄어들수록 가중치를 잘찾은 것)

목적함수에서 미분과 최적화함수를 사용해서 구한다.

미분에서 대표적으로 경사하강법이 있다.

경사하강법: 특정함수가 줄어드는 방향으로 특정변수들의 값을 업데이트 하는 방법

 

정리: 학습이란 머신러닝에는 가중치가 있고 이것들로 예측값이 결정 된다. 예측치와 실제값을 비교해서 얼마나 차이나는지 오차를 계산하고 이를 최소화 하기 위해 가중치를 바꿔가며 오차가 줄어들게 하여 정답에 가깝게하는 것이다.

한번에 최저값으로 만들지 않는 것은 비효율적이기 때문이다.

 

📚Scikit-learn을 사용한 선형 회귀 모델 구현 및 평가

import pandas as pd

import numpy as np
from sklearn.model_selection import train_test_split #데이터 분할 기능
from sklearn.linear_model import LinearRegression #선형 모델을 가져오고 선형 회귀로 지정
from sklearn.metrics import mean_squared_error, r2_score #모델의 성능을 평가하는 메트릭을 가져온다.

 

데이터 분할

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

train_test_split(독립변수, 종속변수, 테스트의 비율, random_state값에 따라 데이터셋을 랜덤하게 분할하게 한다.)

 

선형모델 생성 및 실행

model = LinearRegression() #선형모델이 자동 생성
model.fit(X_train, y_train) #(테스트 데이터, 테스트 정답)넣어주면 자동으로 학습이 진행 된다.

  • X_train: 모델이 학습할 때 사용할 입력 데이터(독립 변수들).
  • y_train: 출력 데이터(종속 변수 또는 타겟값)입니다

 

 

예측

y_pred = model.predict(X_test) #값을 저장할 변수 생성 후 모델에서 predict함수 호출해 테스트할 독립변수를 넣어준다.

 

정확도 평가

mse = mean_squared_error(y_test, y_pred) #0에 가까울수록 좋다
r2 = r2_score(y_test, y_pred) #1에 가까울수록 좋다

 

☑️ 다항회귀

  • 다항 회귀(Polynomial Regression)는 종속 변수와 독립 변수 간의 비선형 관계를 모델링하는 방법
  • 독립변수의 다항식을 사용하여 관계를 모델링 합니다.

다항회귀 차수 선택

  • 다항회귀 차수(degree) : 독립 변수의 최대 차수
  • 차수가 높을수록 모델이 더 복잡해지며 과적합(overfitting)의 위험 존재 → 적절한 차수 선택 필요

📚 Scikit-learn을 사용한 다항 회귀 모델 구현 및 평가

import pansdas as pd

import numpy as np

from sklearn.model_selection import train_test_split

from sklearn.preprocessing import PolynomialFeatures #Features의 차수를 선택해준다.

from sklearn.linear_model import LinearRegression

from sklearn.metrics import mean_squared_error, r2_score

 

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

y = np.array([1, 4, 9, 16, 25, 36]) # 데이터 생성

poly = PolynomialFeatures(degree=2) #2차항까지 만들어주게 설정

X_poly = poly.fit_transform(X) #데이터를 만들어둔 Polynomial생성기에 전달해서 실제로 2차항으로 만든다.

 

X_poly를 실행해보면

array([[ 1.,  1.,  1.],
       [ 1.,  2.,  4.],
       [ 1.,  3.,  9.],
       [ 1.,  4., 16.],
       [ 1.,  5., 25.],
       [ 1.,  6., 36.]])

순서대로 0차항, 1차항, 2차항 값이 나온다.

 

X_train, X_test, y_train, y_test = train_test_split(X_poly, y, test_size=0.2, random_state=42)

#데이터 분할

 

model = LinearRegression()
model.fit(X_train, y_train)

#선형식을 넣는 이유: 위 poly = PolynomialFeatures(degree=2)에서 다항식을 만들어주었는데 이걸

LinearRegression()에 넣으면 다항회귀식으로 나타내주기 때문이다.

#Features을 생성해주는 것 만으로 선형회귀식을 다항회귀식으로 활용가능

 

y_pred = model.predict(X_test)

 

mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f'Mean Squared Error: {mse}')
print(f'R^2 Score: {r2}')

 

☑️ 로지스틱 회귀 

  • 종속 변수가 이진형일 때(즉, 결과가 두 가지 중 하나일 때) 사용되는 통계 기법
  • 로지스틱 회귀는 선형 회귀와 달리 결과값이 0과 1 사이에 위치하게 하기 위해 시그모이드 함수(Sigmoid Function)를 사용합니다.
  • 실제로는 분류모델에 사용한다.

로지스틱 회귀 사용 목적

  • 로지스틱 회귀는 데이터를 학습하여 각 데이터 포인트가 특정 클래스에 속할 확률을 예측합니다.
  • 예를 들어, 유방암 데이터에서는 환자가 암에 걸렸을 확률, 타이타닉 데이터 에서는 승객이 생존할 확률을 예측합니다.

로지스틱 회귀의 비용함수란?

  • 로지스틱 회귀의 비용 함수는 모델의 예측 확률과 실제 레이블 사이의 차이를 측정합니다.
  • 로그 손실 함수(Log Loss) 또는 크로스 엔트로피 손실 함수(Cross-Entropy loss)라고 불립니다.
  • 확률을 높여주어야 한다.
  • 값이 1에 가까울수록 정확한 값이다.(0에 가까우면 잘못한거다.)

 

개념

-m개는 데이터이다. 데이터 전체의 확률을 계산 한다.

-y(i)는 확률 ex)1

-h는 실제로 예측한 값 ex) 0.2

-로그 함수는 값이 작아질수록 굉장히 작은 값이 나온다.

-1 - y(i)는 실제로 아닐 확률 ex)0

 

📚 데이터 로드 및 전처리

import numpy as np

import pandas as pd

from sklearn.datasets import load_breast_cancer # sklearn에 포함된 datasets중 사용할 load_breast_cancer데이터 가져오기

from sklearn.model_selection import train_test_split #test train을 나누기 위한 모듈 import

from sklearn.preprocessing import StandardScaler # StandardScaler는 데이터가있을 때 데이터의 분포를 맞춰주는 역할(데이터 정규화)

 

data = load_breast_cancer() # 데이터 로드

X = data.data #X에 Feature만 가져온다.

y = data.target #데이터 속에 타겟은 맞추기 위한 레이블만 포함 되어있어서 레이블만 가져온다.

 

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

#데이터 분할

 

scaler = StandardScaler() #스케일러 적용해 스케일러 생성

X_train = scaler.fit_transform(X_train)

#만들어진 스케일러에 트레이닝 데이터를 fit해준다. 그러면 스케일러는 학습을 한다

#fit이라는건 학습을 말한다.

#스케일링을 하는 이유는 데이터가 있을때 표준과 표준편차를 정규분포를 따르도록 해주는것

#간단하게 데이터가 평균과 분산이 같도록 바꿔주는 작업

X_test = scaler.transform(X_test)

# X_train에 대해서 평균과 편차를 찾아 정규화 해준다.

# transform은 실제데이터에 적용하는 것을 말한다.

 

📚 모델학습

from sklearn.linear_model import LogisticRegression

from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

# LogisticRegression 모델과 다양한 metrics 가져오기

 

모델 생성 및 학습 

model = LogisticRegression()

model.fit(X_train, y_train)

 

예측

y_pred = model.predict(X_test)

 

평가

print(f"Accuracy: {accuracy_score(y_test, y_pred)}")

print(f"Classification Report:\n{classification_report(y_test, y_pred)}")

print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}")

 

 

9강 강의자료 아래에 타이타닉 데이터를 활용한 전처리 내용 (내용이 길어서 작성은 X, 복습은 필수)

인코딩 부분에서 안좋은 예시로 들어있음 (데이터들을 너무 간단하게 0,1,2로 표현했기 때문)

# 특성과 타겟 분리

X = titanic.drop('survived', axis=1)

y = titanic['survived']

survived는 종속변수라서 학습에 필요X = y(종속변수로 지정)

타이타닉에서 열을 기준으로 survived분리/ 나머지는그대로 놔둔다.

 

 


☑️  회고

 

 

1. 모델훈련에서 무엇을 보고 추가 제거를 하는거지?

 

2. 이상치 대체

df['column_name'] = df['column_name'].apply(lambda x: mean_value if x < lower_bound or x > upper_bound else x)

  • 람다 함수lambda는 이름 없이 간단하게 한 줄로 함수를 정의
  • lambda x: x는 column_name의 각 개별 값을 나타냅니다.
  • if x < lower_bound or x > upper_bound: 만약 x가 lower_bound(하한값)보다 작거나 upper_bound(상한값)보다 큰 경우, 즉 값이 범위 밖에 있는 경우,
  • mean_value: 그 값을 **평균값(mean_value)**으로 대체합니다.
  • else x: 그렇지 않다면, 값은 변경하지 않고 그대로 유지됩니다.

3. 인코딩 부분 실습하면서 이해필요

 

4. 데이터 분할

train_test_split() 함수

  • 이 함수는 주어진 데이터를 훈련용 데이터 테스트용 데이터로 나눕니다. 훈련 데이터는 모델을 학습시키는 데 사용되고, 테스트 데이터는 모델의 성능을 평가하는 데 사용됩니다.

5. 정확도 평가

**MSE (Mean Squared Error)**와 **R² (R-squared, 결정계수)**는 회귀 모델의 성능을 평가하는 데 사용되는 지표입니다. 두 지표는 서로 다른 측면에서 모델의 정확도를 평가합니다.

r2 = r2_score(y_test, y_pred) 

 R²는 모델이 전체 변동을 얼마나 잘 설명하는지 나타내는 지표로, 타겟 변수의 변동성 중에서 독립 변수가 얼마나 설명할 수 있는지를 보여줍니다.  

 

mse = mean_squared_error(y_test, y_pred)
평균 제곱 오차는 모델이 예측한 값과 실제 값 간의 차이를 평가하는 지표로, 그 차이(오차)의 제곱 평균을 계산합니다.

 

6. 모델 학습

accuracy_score, classification_report, confusion_matrix

 

7. .predict() 함수

1) 선형회귀

LinearRegression 모델에서 .predict()를 사용하면 주어진 입력 데이터에 대해 연속적인 값을 예측합니다.

2) 로지스틱 회귀

LogisticRegression에서 .predict()를 사용하면 주어진 데이터에 대한 클래스 라벨을 예측합니다. 로지스틱 회귀는 이진 또는 다중 클래스 분류를 수행할 수 있습니다.

3) 로지스틱 회귀에서 확율 예측

로지스틱 회귀와 같은 분류 모델에서는 .predict_proba() 메서드를 사용하여 각 클래스에 속할 확률을 예측할 수 있습니다.

  • 도전과제 1번 
  • 도전과제 2번 
  • 도전 과제 3번 
  • 총평 
  • 새롭게 알게 된것 
  • 까먹은 것
  •  궁굼한 것

 

도전과제 1번

숫자 맞추기 게임 (선택)

추가 도전 과제

  • 플레이어가 입력한 숫자가 범위를 벗어날 경우, 적절한 안내 메시지를 출력하여 유효한 범위 내의 숫자를 입력하도록 유도하세요.

        if user_num > 10: #입력 값이 10보다 클 때 작동
            print(f'숫자가 너무 큽니다. 10 이하의 숫자만 입력해주세요.') #위 조건이 충족 되었을 때 출력 되는 메세지 작성

  • 플레이어가 게임을 반복하고 싶을 경우, 게임 재시작 여부를 묻고 그에 따라 게임을 초기화하거나 종료하는 기능을 추가하세요.

    restart = input('다시 시작하겟습니까? (y/n)') #다시 시작여부 입력 받는 restart 생성

    if restart != 'y': #y가 아닐 때 작동
        print('게임이 끝났습니다.')  #위 조건에 맞으면 출력 되는 메세지       
 
    
        break #조건 충족 시 멈춤

 

 

 

 


 

 

 

도전과제 2번 

추가 도전 과제

  • Person 클래스 생성자에서 사용자의 성별 입력값에 대한 유효성 검사를 추가해주세요.

while True:
    gender = input('성별을 입력해주세요 (male OR female): ').strip().lower()  # 소문자로 변환하여 비교를 용이하게 함
    if gender == 'male' or gender == 'female':  # gender 조건
        break
    else:
        print('male과 female 중 하나만 입력해주세요.')

 

  • Person 클래스에 나잇대에 맞는 인사 메시지를 출력할 수 있도록 greet() 함수를 추가해주세요

        
    def greet(self): #조건식에 따라 성인 미성년자를 구분해서 인사하는 함수 추가
        if age >= 20:
            print("안녕하세요!name님 성인이군요!!")
        else:
            print("안녕하세요!name님 미성년자군요!!")
    

위 코드를 실행 시킬 때 

person1.display(), person1.greet() 각각 호출해서 함수를 작동 시켜야하는데 한번에 작동 시키는 방법이있을까?


      


 

 

도전 과제 3번

추가 도전 과제

1. Python 라이브러리 함수를 사용하여 인구 데이터(pop_kor.csv) 파일을 불러오고, DataFrame을 출력해주세요.

  • Quiz에서 수행한 DataFrame의 구별 index를 기준으로 merge를 할 것이므로, index를 셋팅해서 불러와 주세요.

pop_kor_df = pd.read_csv("pop_kor.csv", index_col='구별', encoding='utf-8') 

#csv파일 가져오기, '구별' 열을 인덱스 지정, 한글파일 읽어오기

 

df_csv = pd.DataFrame(pop_kor_df)

#df_csv라는 데이터 프레임 생성

 

df_csv2 = df_csv.dropna() 
df2 = df.dropna() 

#결측치 존재하는 행 제거

 

2. join 을 사용하여 Quiz에서 수행한 DataFrame과 인구 데이터 DataFrame을 merge하고, DataFrame을 출력해주세요.

 

df3 = df2.join(df_csv2)

 #df2와 df_csv2를 join해서 df3 생성 

 

df3.dropna()

 #df3에서 결측치가 존재해 sort가 진행 되지않아 제거

 

3. 새롭게 merge 된 DataFrame에서 검거율 기준으로 오름차순 정렬 후, DataFrame을 출력해주세요.

 

sort_df = df3.sort_values(by = '검거율',ascending=True)  

#검거율을 기준으로 정렬

 

 

 


 

 

 

총평
 

도전과제 1-1: 간단한 조건문은 쓰는데 익숙해지고있다.

 

도전과제 1-2: 조건을 추가 할 때 위치는 어느정도 감을 잡은 듯. 약간 복잡해져도 잘 모르겟어서 검색을 통해 진행했다.                            코드 전체를 보는 감각이 부족하다.


도전과제 2-1번: 어제 걸었던 조건식으로 해결 가능할 것 같아 건들이지 않았다.

 

도전과제 2-2번: 처음에는 greet함수 문법이 생각 나지 않아 검색해서 첫 줄 문법만 보고

                       작성하였고 매개변수인 self, 조건식, print문은 직접 작성했다.

 

도전과제 3-1번: 데이터 불러오기는 익숙해 져서 코드를 보지 않아도 작성 가능해졌다..

 

도전과제 3-2번: 데이터끼리 병합하는 단계는 강의보고 따라 했었지만 기억나지 않았고 검색을 통해 작성하였다.

                         병합하는 방법과 예시들이 많았기에 실습을 더 진행해 보아야 할 것 같다.

 

도전과제 3-3번: 결측치 확인을 하지 않아 진행이 안되었지만 결측치 제거 후 진행이 깔끔해짐

                          결측치 처리의 중요성을 인지 했습니다.

 

총평: 조금씩 익숙해지고 있지만 문법, 함수 / 메서드의 기능 등 부족한 부분이 많다.

 

 


 

 

새롭게 알게 된것

 

1. 파일을 read 할 때 인덱스를 정해서 가져오는 방법

df = pd.read_csv('test.csv', index_col = "")

#index_col = " "과 숫자로 가져오는 방법이있다.

 

2. join 사용 문법

DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)

 

  • other: 결합할 다른 데이터프레임
  • on: 결합할 기준이 되는 열이나 인덱스 (기본값은 인덱스)
  • how: 결합 방식 (left, right, outer, inner)
  • lsuffix, rsuffix: 동일한 열 이름이 있을 때 구분을 위한 접미사
  • sort: 결합된 결과를 정렬할지 여부 (기본값은 False)

 

3. `\t`는 탭을 의미

 

4. `\n'`은 줄바꿈을 의미

 

5. 같은 줄에 여러 함수 쓰는 법 

print("first");print("second")

 

6. 줄바꿈 없이 출력 방법 end = ""

print("first", end=""); print("second")

 

7. 바인딩이란

 변수 속성을 이름, 자료형, 자료값으로 할당 하는 것

 

8. 변수를 출력할 때 기호 붙이기(s와t는변수)

print(s+"!",t)

 

9. 슬라이싱의 기능

string = "홀짝홀짝홀짝"
print(string[::2])

시작인덱스:끝인덱스:오프셋(오프셋은 몇칸씩 건너 뛸지 지정)

                                              (오프셋을 -1로 지정하면 문자열을 뒤집어서 출력 한다.)

 

10. 문자열에 값 넣기 % formatting

포맷 코드설명

%s 문자열 (String)
%d 정수 (Integer)
%f 부동소수점 (Float)
%x 16진수 (Hexadecimal)
%o 8진수 (Octal)
%% 퍼센트 기호 출력

문자열 포맷팅 ex)

name = "Alice"

greeting = "Hello, %s!" % name

print(greeting) # Hello, Alice!

 

2가지 다른 문자열 포맷팅 ex)

message = '이름: %s, 나이: %d' %(name, age)

 

11. 문자열에 값 넣기 .format()

print("이름: {} 나이: {}".format(name, age))

 

12. 문자열에 값 넣기 f"

print(f"이름: {name} 나이: {age}")

 

13. 첫글자만 대문자로 .capitalize()

#첫 글자에 숫자나 기호가 있을 때는 변화 없음

 

14. 특정 접미사로 끝나는지 확인 .endswith()

string.endswith(suffix[, start[, end]])

 

  • suffix: 확인할 접미사 문자열 또는 문자열의 튜플.
  • start (선택적): 검색을 시작할 위치(인덱스).
  • end (선택적): 검색을 끝낼 위치(인덱스).

15. 특정 접두사로 확인

file_name.startswith("2020")

 

 


 

 

 

 

까먹은 것

 

1. merge 사용 문법

DataFrame.merge(right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, suffixes=('_x', '_y'))

 

  • right: 결합할 다른 데이터프레임.
  • how: 조인 방식 (default: 'inner').
    • 'left': 왼쪽 데이터프레임을 기준으로 결합.
    • 'right': 오른쪽 데이터프레임을 기준으로 결합.
    • 'inner': 교집합 (공통된 값만 결합).
    • 'outer': 합집합 (모든 값 결합, 일치하지 않는 값은 NaN).
  • on: 결합할 공통 열의 이름 (열 이름이 같을 때 사용).
  • left_on: 왼쪽 데이터프레임에서 결합할 열 이름.
  • right_on: 오른쪽 데이터프레임에서 결합할 열 이름.
  • left_index, right_index: 인덱스를 기준으로 결합할지 여부.
  • suffixes: 동일한 열 이름에 대한 접미사 (기본값: ('_x', '_y')).

2. 변수에서 글자 지정해서 출력

letters = 'python'

print(letters[0], letters[2])

 

3. replace 메서드

text = "banana"
new_text = text.replace("a", "o") # new_text = text.replace("a", "o", 1) # 1번만 치환
print(new_text)  # "bonono"         # "bonana"

 

text = "apples are red, apples are sweet"
new_text = text.replace("apples", "oranges") # ("apples", "oranges",1)을 하면 1번만 치환
print(new_text)  # "oranges are red, oranges are sweet" # "oranges are red, apples  are sweet" 

 

4. 문자열을 나누어 리스트로 반환 .split()

text.split(sep=None, maxsplit=-1)

 

  • sep: 문자열을 분리할 때 사용할 구분자. (기본값은 공백)
  • maxsplit: 분리할 최대 횟수. (기본값은 -1, 즉 제한 없음)

 

4-1 공백 기준 분리 # words = text.split()

4-2 특정 구분자를 기준으로 분리 # fruits = text.split(",")

4-3 최대 분리 횟수 지정 # parts = text.split(", ", 2) =>  ['one', 'two', 'three, four']

4-4 한 글자씩 분리 list로 분리하는게 적합하다. # letters = list(text)

 

5. .apply() 적용 방법

apply(func, axis=0, raw=False, result_type=None, args=(), **kwds)

 

  • func: 적용할 함수. 직접 정의한 함수나 내장 함수를 사용할 수 있습니다.
  • axis: 함수를 적용할 축을 선택.
    • 0 (기본값): 열(column) 단위로 함수 적용.
    • 1: 행(row) 단위로 함수 적용.
  • raw: True일 경우, 행이나 열을 ndarray로 전달. (기본값은 False)
  • result_type: 결과 형식을 지정 (expand, reduce 등).
  • args: 추가적인 인자를 전달.

 

 

6. 대/소문자 upper()/lower()

대문자로 바꾸는 ex)

ticker = "btc_krw"

ticker1 = ticker.upper()

print(ticker1)

 

입력값을 대/소문자로 바꿔서 받게하는 ex)

data = input("적어 봐").upper() / .lower()

 

7. 리스트 사이에 요소 넣기 .insert()

movie_rank = ['닥터 스트레인지', '스플릿', '럭키', '배트맨']

movie_rank.insert(1,'슈퍼맨')

#(위치 지정, 넣을 요소 지정)

 

 


 

 

 

궁굼한 것

 

1번은 y가 아닌 다른 어떤 문자나 숫자가 와도 프로그램이 종료 되는데  해결 방법을 못찾음 

 

1번에서 숫자가 아닌 다른 문자나 공백이 써졌을때를 대비한 조건문도 넣어보자

 

2번은 person1.display(), person1.greet() 각각 호출해서 함수를 작동 시켜야하는데 한번에 작동 시키는 방법이있을까?

 

3번은 정확한 건지 모르겟음

 

  • 개인 과제 2번
  • 개인 과제 3번
  • 총평
  • 알게 된 것들
  • 까먹은 것들

 

 

2. 클래스 함수 사용

 

과제 내용

  • 이름, 성별, 나이를 입력받고, 이를 출력하는 프로그램을 작성해주세요.

4차 시도

class person: #person 클래스 정의
    def __init__(self, name, gender, age):#초기화 메서드
        self.name = name #속성정의
        self.gender = gender
        self.age = age
        
    def display(self): #정보출력함수 적용
        print(f"""이름:{self.name},성별: {self.gender}
나이: {self.age}""")   
    
name = input('이름을 입력해주세요') #객체별 input함수 적용
gender = input('male  OR female')
age = input(int('나이를 숫자로 입력해주세요'))

whlie True:
    if gender == 'male' or gender == 'female': #gender 객체에 조건 추가
        break
    else:
        print('male과 female중 하나만 입력해주세요') #조건에 맞지 않을 때 사용할 문장
whlie True:
    if age > 0: #age 객체에 조건 추가
        break
    else:
        print('0보다 큰 숫자만 입력해 주세요') #조건에 맞지 않을 때 사용할 문장
    
person1 = person({self.name}, {slef.gender}, {self.age})

 

#팀 회의 때 질문해보고 입력값을 어떻게 넣는지 듣고 다시 display()함수와 조건문을 추가해 써보았다.

 

그래서 코드 작성을 위와 같이 하였고 결과는

SyntaxError: invalid syntax

가 나왔다.

 

더 이상 진행이 되지않아 GPT에게 위 코드의 잘못된 부분을 물어 보았다.

 

 

  • whlie 오타 => while
  • input(int('나이를 숫자로 입력해주세요')) => int(input( '나이를 숫자로 입력해주세요' ))
  • person1 = person({self.name}, {self.gender}, {self.age}): => person1 = person(name, gender, age)                     - {}는 문자열 포맷팅을 의미하지만, 여기서는 필요 없습니다. 단순히 변수만 넘기면 됩니다.                                         -  self는 인스턴스 메서드에서만 사용하며, 객체 생성 시에는 사용하지 않아야 합니다.
  • while조건문으로 객체 조건 걸기

수정 된 코드

class Person: # 클래스 이름은 관례상 첫 글자를 대문자로 시작합니다.

        def __init__(self, name, gender, age): # 초기화 메서드

               self.name = name # 속성 정의

               self.gender = gender

               self.age = age

 

       def display(self): # 정보 출력 함수

               print(f"이름: {self.name}, 성별: {self.gender}, 나이: {self.age}") 

 

name = input('이름을 입력해주세요: ')

while True:

       gender = input('성별을 입력해주세요 (male OR female): ').strip().lower() # 소문자로 변환하여 비교를 용이하게 함

       if gender == 'male' or gender == 'female': # gender 조건

             break

       else:

             print('male과 female 중 하나만 입력해주세요.')

 

while True:

     try:

      age = int(input('나이를 숫자로 입력해주세요: ')) # 나이 입력을 숫자로 받음

      if age > 0: # age 조건

            break

      else:

            print('0보다 큰 숫자만 입력해 주세요.')

      except ValueError:

            print('유효한 숫자를 입력해주세요.') # 숫자가 아닌 값을 입력했을 때 예외 처리

 

person1 = Person(name, gender, age)

 

person1.display()

 

 

 


 

 

 

 

 

3. Python 라이브러리로 데이터 분석하기 (필수)

과제 내용

  • Python 라이브러리를 활용하여 주어진 데이터(.xlxs)를 분석 Quiz를 수행해주세요.

 

Quiz

1. Python 라이브러리 함수를 사용하여 엑셀 파일을 불러오고, DataFrame을 출력해주세요.

import pandas as pd

data_df = pd.read_excel("관서별 5대범죄 발생 및 검거.xlsx")

df = pd.DataFrame(data_df)

df

 

2. 각 경찰서(관서명)를 해당 구 이름으로 매핑하여 '구별'이라는 새로운 column을 생성하고, DataFrame을 출력해주세요.

1차 시도

df['구별'] = 

'서대문서': '서대문구', '수서서': '강남구', '강서서': '강서구', '서초서': '서초구',
'서부서': '은평구', '중부서': '중구', '종로서': '종로구', '남대문서': '중구',
'혜화서': '종로구', '용산서': '용산구', '성북서': '성북구', '동대문서': '동대문구',
'마포서': '마포구', '영등포서': '영등포구', '성동서': '성동구', '동작서': '동작구',
'광진서': '광진구', '강북서': '강북구', '금천서': '금천구', '중랑서': '중랑구',
'강남서': '강남구', '관악서': '관악구', '강동서': '강동구', '종암서': '성북구', 
'구로서': '구로구', '양천서': '양천구', '송파서': '송파구', '노원서': '노원구', 
'방배서': '서초구', '은평서': '은평구', '도봉서': '도봉구'

#SyntaxError(맵핑이라는 단어를 보지 못한채 진행한 결과)

 

2차 시도

map_df = {'서대문서': '서대문구', '수서서': '강남구', '강서서': '강서구', '서초서': '서초구',
'서부서': '은평구', '중부서': '중구', '종로서': '종로구', '남대문서': '중구',
'혜화서': '종로구', '용산서': '용산구', '성북서': '성북구', '동대문서': '동대문구',
'마포서': '마포구', '영등포서': '영등포구', '성동서': '성동구', '동작서': '동작구',
'광진서': '광진구', '강북서': '강북구', '금천서': '금천구', '중랑서': '중랑구',
'강남서': '강남구', '관악서': '관악구', '강동서': '강동구', '종암서': '성북구', 
'구로서': '구로구', '양천서': '양천구', '송파서': '송파구', '노원서': '노원구', 
'방배서': '서초구', '은평서': '은평구', '도봉서': '도봉구'}

#맵핑(비교)을 하기 위한 mpa_df 생성

 

df['구별'] = df['관서명'].map(map_df).fillna('구 없음')

#'구별' 이라는 새로운 열 생성 하며 관서명 열에 .map() 함수를 적용시켜 맵핑 진행

# fillna함수로 결측치에 '구 없음'값 지정

 

3. pivot_table 을 사용하여 관서별 데이터를 구별 데이터로 변경하고, 같은 구의 경우에는 sum을 적용하여 더해주세요. (index : 관서 이름 -> 구 이름)

1차 시도

pivot = pd.pivot_table(df, index = '구별', values = 소계(발생), 소계(검거), 살인(발생), 살인(검거), 강도(발생), 강도(검거), 강간(발생), 강간(검거), 절도(발생), 절도(검거), 폭력(발생), 폭력(검거), aggfunc = 'sum')

#syntaxError columns을 지정하지 않고 모든 값이 다 나와있는 참고자료를 보고 values에 모든열 추가.

 

2차 시도

pivot = pd.pivot_table(df, index = '구별', aggfunc = 'sum')

#결과 값에 관서명 열이 사라지지 않음 (colums과 valuse를 지정하지 않고 시도)

pivot_dropped = pivot.drop(columns=['관서명'])

#drop함수를 사용해서 관서명 열 삭제

 

4. 구 없음 행은 drop 을 활용하여 삭제해주세요.

pivot_dropped.drop(['구 없음'])

 

5. 각 범죄 별로 검거율을 계산하고, 각 검거율 데이터 column을 DataFrame에 추가해주세요.

pivot_dropped = df #이름이 길어져서 간단하게 바꿈

 

df['강간검거율'] = df['강간(검거)'] / df['강간(발생)'] * 100
df['강도검거율'] = df['강도(검거)'] / df['강도(발생)'] * 100
df['살인검거율'] = df['살인(검거)'] / df['살인(발생)'] * 100
df['절도검거율'] = df['절도(검거)'] / df['절도(발생)'] * 100
df['폭력검거율'] = df['폭력(검거)'] / df['폭력(발생)'] * 100

#범죄별 검거율 열 생성

 

1차 시도

df['검거율'] = df.mean(df['강간검거율'], df['강도검거율'], df['살인검거율'], df['절도검거율'], df['폭력검거율'])

#총 검거율을 mean함수로 설정 해보려고 했으나 TypeError

 

df['강간검거율'] = df['강간검거율'].astype(int)
df['강도검거율'] = df['강도검거율'].astype(int)
df['살인검거율'] = df['살인검거율'].astype(int)
df['절도검거율'] = df['절도검거율'].astype(int)
df['폭력검거율'] = df['폭력검거율'].astype(int)

# float이라 값이 너무 커서 안되나 싶어서 정수 변환시킴 

 

2차시도

df['검거율'] = df[['강간검거율', '강도검거율', '살인검거율', '절도검거율', '폭력검거율']].mean(axis=1)

#검거율 열을 생성하며 df안의 특정 열들을 리스트형식으로 가온다 표시하고 mean(axis=1)으로 평균값을 계산하며 행을 기준으로 계산 지정

 

6. 필요없는 column을 del 을 사용하여 삭제해주세요.

1차 시도

del.df['소계(발생)', '소계(검거)', '살인(검거)', '강도(검거)', '강간(검거)', '절도(검거)', '폭력(검거)']

# KeyError 인터넷 검색 후

del df['소계(발생)']

# 정상 작동 하는 것을 확인

del df['소계(검거)'], df['살인(검거)'], df['강도(검거)'], df['강간(검거)'], df['절도(검거)'], df['폭력(검거)']

# 정상작동

한번에 적용하는 방법이 있을까?

 

7. DataFrame의 컬럼명을 rename 을 사용하여 변경해주세요.

df = df.rename(columns = { '강간(발생)' : '강간', '강도(발생)' :'강도', '살인(발생)':'살인', '절도(발생)':'절도', '폭력(발생)':'폭력' })

#검색을 통해 작성법을 보고 적었다.

#정상작동

 

 

 

 

 

 


총평

각 요소의 지칭 단어, 오타, 함수 사용 문법, 코드 작성 순서에 아직 많이 미숙하다.

 

최대한 GPT도움을 안받고 어떤걸 어떻게 해야하는지 알아가 보면서 스스로 하려했지만 막히는 부분이 많았다.

아직 코드 구조에 대해 정확하게 파악한게 아니니 어쩔 수 없다는 생각을 하지만

 

그래도 GPT도움없이 익숙해져 나갈 것이고

 

GPT의 도움을 받았을 땐 코드 하나하나 뜯어 먹어봐야겟다.

 

 


 

 

 

 

새롭게 알게 된 것들

 

1. try except 

- 프로그램 실행 도중 예외(오류)가 발생했을 때 프로그램의 비정상 종료를 막거나 사용자에게 오류 정보를 제공한다. 

try:
    #오류(예외) 발생 가능성있는 코드 위치

except ValueError: #오류(예외)코드 위치  
    #오류 발생시 수행 코드 위치


2. .strip() ※ .lstrip()  .rstrip() 

- 문자의 공백을 제거해 사용자 입력 값을 계산하기 편하게 만든다.

※앞쪽(왼쪽)문자열 제거 / 뒤쪽(오른쪽)문자열 제거

 

3. .lower()

- 문자열을 모두 소문자로 변환 시킨다.

- 사용자 입력값을 동일하게 만드는 역할

 

4. .isdigit() 

-모두 숫자로 이루어져있는지 확인한다.  #age if조건에 추가했다면 try except 구문 없이 else로 끝낼 수 있다.

 while True:
        나이 = input("나이를 입력하세요: ").strip()
        if 나이.isdigit() and int(나이) > 0:  # 나이가 양의 정수인지 확인
            나이 = int(나이)
            break
        else:
            print("잘못된 입력입니다. 양의 정수를 입력해주세요.")

 

5. 기존 데이터와 2차 데이터를 맵핑 시키기

- {}중괄호 안에 기존 데이터와 : 을 사용해 새로운 정보를 작성 #{서울 : 서울시, 대구 : 대구시}

-위 정보를 본인이 정한 언어로 데이터화 #map_ing = {서울 : 서울시, 대구 : 대구시}

df['시를 붙임'] = df['시 없음'].map(map_ing)

df['시를 붙임'] # 기존 df에 맵핑의 값을 넣을 '시를붙임' 열 생성

 df['시 없음'].map(map_ing)  #기존 df의 '시 없음' 열과 map_ing데이터를 map() 함수로 맵핑 

 

6. if __name__ == "__main__"

- 모듈이 직접 실행될 때만 특정 코드를 실행할지 여부를 제어

- 다른 파일에서 임포트하면, if __name__ == "__main__": 아래의 코드는 실행되지 않는다.

 

7. del 을 활용한 삭제 방법

del df['소계(발생)']

#del과 데이터 사이에는 띄어쓰기만 존재함

#[] 대괄호안에 데이터의 없앨 요소 지정

#여러가지를 삭제시킬 때는 del df['소계(발생)'], df['소계(검거)'] 처럼 하나하나 작성해야함

 

 


 

 

 

생각지 나지 않던 것들

 

1. 클래스의 이름 첫글자는 대문자

 

2. 클래스란? #Person

- 제품의 설계도 

 

3. 객체란? # person1

- 설계도로 만든 제

- 객체는 클래스의 인스턴스

- 객체는 속성과 메서드를 가질 수 있다.

 

4. 속성이란? # name, gender, age

- 객체의 데이터를 가리킴

- 클래스안의 변수

 

5. 메서드란?#def __init__ / def display()

-객체가 어떻게  작동할지 정하는 함수

 

6. 인스턴스란?#person1 안의 name, gender, age

 

7. .fillna('구 없음') 

-결측치를 처리할 때 사용하며 결측치가있는 nan, none에 '구 없음' 값을 넣을 수 있다.

 

8. pivot테이블 작성 방법

pivot = pd.pivot_table(df, index='', columns='', values='', aggfunc='')

#df의 데이터중 index(열), columns(행)을 기준으로  valuse의 값들을 aggfunc로 지정한 함수 적용 시킨 pivot이란 테이블 생성

 

9. drop함수로 행삭제 열삭제

pivot_dropped.drop(['구 없음'])

#행 삭제

pivot_dropped = pivot.drop(columns=['관서명'])

#열 삭제

 

10. .astype()

문자열 변경 메서드

 

11. 테이블에 함수 적용 시 행기준 여기준 잡기

.mean(axis=1)

#axis=0은 열기준

#axis=1은 행기준

 

12. rename작성법

df = df.rename(columns = {'':''})

#rename메서드안에 columns = {'바뀌기 전' : '바뀐 뒤"}

 

  • 멀티/복합인데스 
  • 데이터프레임 구조화다시하기/크기 조정 
  • 판다스 실습 
  • 특강( 학습법 마음가짐
  • 회고

 

 

6-1

멀티/복합인데스

데이터프레임에서 데이터의 인덱스를 다차원으로 구성하는 방법

이개념들은 데이터가 계층적 구조를 띄거나 다차원 구조를 가질 때 유용하게 사용 가능

 

멀티인덱스

하나 이상의 인덱스를 사용하여 데이터프레임의 행과 열을 구조화하는 방법

다차원 데이터를 보다 효율적으로 관리하고 분석

멀티인뎃스를 사용하면 계층적으로 멀티인덱스를 생성하고 이를 데이터 프레임의 인덱스로 활용하게 된다.

현재는 예시이기 때문에 인덱스 계층을 써놓았지만 나중에 활용방법들이 나올 것이다.

 

1. 멀티인덱스 생성

1) set_index을 사용한 멀티인덱스 코드

#데이터 프레임을 작성 한 뒤

df_multi_index = df.set_index(['도시', '년도']) #도시와 년도를 인덱스로 가져온다.

 

2) pd.MultiIndex.from_tuples()을 사용한 멀티인덱스 코드

멀티인데스를 튜플로 직접 생성

index = pd.MultiIndex.from_tuples([(리스트, 리스트1-1),(리스트2, 리스트2-1)], names = [리스트3, 리스트3-3]) 

#인덱스 계층 설정

 

df_multi_index = pd.DataFrame({'인구수': [9700000, 9720000, 3400000, 3450000]}, index=index)

#데이터프레임 설정

 

pd.MultiIndex #멀티 인데스 객체를 생성

 

.from_tuples() #멀티인덱스를 구성할 튜플의 리스트 받아서 멀티 인덱스 객체를 반환해주는 작업

(리스트, 리스트1-1) 튜플은 인덱스의 각 계층에서 사용할 값을 나타냄 =>1계층에서 리스트1, 2계층에서 리스트1-1

 

names = [리스트3] #name은 멀티인덱스에 어떤 이름을 지정할지 나타냄

1계층은 리스트3, 2계층은 리스트3-3

 

2. 멀티인덱스 데이터 접근

1) loc[]을 사용한 접근

print(df_multi_index.loc['서울']) #서울(레이블)이라는 인덱스의 데이터 선택 

tip. 위에서 인덱스를 설정했기 때문에 loc을 사용해 접근 시 인덱스가 또 사용 됨

tip. 위에서 설정하지 않은 인덱스인 '인구수'로 잡히는데 시리즈객체를 이해해야한다.

     시리즈 객체는 단일 열을 나타내는데 원래 데이터 프렝임에서 선택 된 이름은 자동으로 시리즈의 인덱스로 설정 된다.

 

2) 슬라이싱을 사용한 접근

계층적으로 구성된 데이터를 만들어 놓았기 때문에 특정 범위의 구간이나 데이터를 쉽게 선택할 수 있다.

멀티 인덱스는 슬라이싱을 통해 특정 구간의 데이터를 쉽게 선택할 수 있습니다.

 

df_multi_index = df_multi_index.sort_index()

print(df_multi_index.loc['부산':'부산'])

 

tip. loc으로 검색할 때 기본적으로 인덱스는 정렬 되어있다 판다한다. 이때 인덱스가 정렬 되어있지 않으면 판다스는 효율적으로 검색하기 위해 인데스의 정렬 수준을 확인한다. 키가 정렬수준이 안좋으면 오류를 발생시킨다.(검색 수준이 보장되지않으면 에러를 발생 시킨다.)

=>  인덱스를 정렬하면 된다.

df_multi_index = df_multi_index.sort_index(ascending = True)

 

3) xs()를 사용한 멀티인덱스 교차 선택

특정 레벨을 기준으로 그 데이터를 추출하고 그 레벨을 제거해서 나머지 데이터를 반환한다.

 

-XS()코드

print(df_multi_index.xs('서울', level='도시')) #서울에 대한 데이터만 가져온다

레벨을 넘어서 데이터를 선택한다는건 어떤 의미?

 

xs()를 이용해서 서울에 대한 데이터만을 가져왔는데 그 과정에서 어떤게 추출되고 제거 되었는지 이해가 안간다.

 

 

3. 복합인데스의 활용

 

1) sort_index()

정렬하기

 

2) unstack과 stack으로 인덱스 변환

 

-unstack활용

df_unstacked = df_multi_index.unstack(level='년도') #인덱스를 열로 반환한다.

-stack활용

df_stacked = df_unstacked.stack() #인덱스로 바꿀 수 있다.

 

 

4. 멀티인덱스 응용

그룹화와 함께 사용한다.

 

1) 그룹화란?

데이터를 데이터를 특정 기준에 따라 나누어서 그룹에 대한 집계 연산을 수행하는 것

 

2) 멀티인덱스란?

인덱스가 2개이상의 계층으로 구성 되어서 데이터를 계층적으로 다처원적 특성을 반영할 수 있게 하는것

 

3) 조합

2개를 조합하면 그룹화한 데이터를 멀티인덱스로 변환하게 되고 각 그룹에 대한 집계결과를 계층적으로 반환하게 된다.

=> 데이터의 관계를 더 명확하게할 수 있고 다차원적인 분석이 가능해진다.

 

4)코드

#데이터프레임 설정 후

grouped_df = df.groupby(['도시', '년도']).mean() #그룹화 시키기

print(grouped_df)

(이렇게 그룹화를 진행했을 때 grouped_df.INDEX로 인덱스를 확인했을 때 자동으로 멀티인덱스가 설정 된것을 확인할 수 있다.)

그래서 grouped.loc[" "]을 했을때 데이터를 편하게 가져올 수 있다.

 

 


 

6-2

데이터프레임 구조화다시하기/크기 조정

 

1. 데이터프레임 구조화 다시하기

데이터를 원하는 형태로 변형할 수 있습니다.

 

1) 피벗(pivot)

열 데이터를 행 또는 열로 이동시켜 새로운 데이터프레임을 만든다.

이는 데이터를 재구성하고 분석하는 데 매우 유용합니다.

 

-활용

하나의 테이블이 있는데 서브테이블을 만들고싶을 때

 

-코드

pivot_df = df.pivot(index='날짜', columns='도시', values='온도')

#도시를 기준으로 날자를index로 온도를 값(행과 열의 교차지점에 값으로 사용 될 것)으로표현

tip. values에 값을 지정하지 않고 columns만 열을 지정하면 다른 모든 열이 값으로 사용 된다.

 

2) 변경(melt)

피벗된 데이터를 다시 긴 형식(long format)으로 변환할 때 사용된다.

이는 여러 열을 하나의 열로 통합하는 데 유용.

 

-활용

피벗 된 데이터를 다시 긴데이터 형식으로 만들 때.

여러열을 하나의 열로 축소하고 데이터의 다른 열들은 식별자 변수로 남게 되면서 재구조 할 수 있다.

 

-코드

melted_df = pd.melt(df, id_vars=['날짜', '도시'], value_vars=['온도', '습도'], valuse = 'test')

 

pd. melt #멜트 메서드 사용

df  #변환 할 데이터 프레임

id_vars #식별자 변수로 사용 할 열들 지정

value_vars #값으로 녹여낼 열 지정

valuse = 'test' #값(valuse)의 이름을 지정

 

3) 스택(stack)

열 데이터를 인덱스의 하위 레벨로 이동

기본적으로 모든 열을 인덱스로 바꿔준다.

 

-코드

#데이터 프레임 설정 한 후

df =df.set_index('날짜') #날짜 데이터를 인덱스로 설정

 

df = df.stack()#데이터프레임에 stack()적용

 

df.index #인덱스를 확인하면 모든 열들이 인덱스인 날짜의 하위레벨로 인덱싱화 된 것을 확인 된다.

 

4) 언스택(unstack)

하위레벨의 인덱스를 열 데이터로 바꿔준다

 

-코드

unstacked_df = stacked_df.unstack() #위의 stacked_df에 unstack() 사용하고 unstacked_df설정

 

tip. stack()을 진행한 후에 바로 unstck()은 진행 되지 않을 수 있다.

멀티인덱스 레벨에 중복 된 값이 있다면 오류 

스택을 사용해서 멀티인덱스 구조가 적절하지않으면 오류

 

2. 데이터프레임 크기조정

 

1) 열 추가하기

 

-코드

#데이터프레임 생성 후

df['날씨'] = ['맑음', '흐림', '맑음', '흐림'] #데이터 프레임에 추가할 열과 값들을 지정

 

2) 행/열 삭제하기

 

-열 삭제 코드

#데이터프레임 생성 후

df_dropped = df.drop(columns=['습도']) #데이터프레임에서 삭제할 columns지정하고 df_dropped 데이터프레임 설정

 

tip. 원본에 영향을 주지 않기 때문에 영향을 주기 위해선 새로운 데이터프레임이 아닌 기존 데이터 프레임에 적용 시켜야한다.

df = df.drop(columns=['습도'])

 

-행 삭제 코드

df_dropped_row = df.drop(index=0) #drop함수 안에 인덱스=0을 지정하여 첫번째 행 삭제

 

 


 

 

6-3

판다스 실습

전체데이터에 대한 전처리

 

데이터 딕셔너리를 보고 각 데이터들의 특징을 파악한 뒤

 

# 실습할 데이터 다운 후 

 

order_items_df = pd.read_csv('order_items.csv')  #파일 가져오기

payment_df = pd.read_csv('payments.csv')

customer_df = pd.read_csv('customers.csv')

order_df = pd.read_csv('orders.csv')

products_df = pd.read_csv('products.csv')

 

파일의 위치를 파이썬 파일과 같은 경로에 두어야한다.

나는 파이썬 파일이 어디에 생성 되는 건지 찾지 못해 애먹었지만 

jupyter home에서 파일을 열어 위치를 찾고 다운받은 파일을 옮겨 주었다.

그러면 쥬피터나 vscode에서 파이썬 파일을 만들 때 위치 지정을 해줄수있나?(파일들이 지저분함)

오후 회의때 질문 해보기

 

order_items_df.isnull().sum() #결측치 확인

payment_df .isnull().sum() 

customer_df.isnull().sum()

order_df.isnull().sum()

products_df.isnull().sum()

# order_df와 products_df 에서 결측치 확인

 

tip.결측치를 찾는 방법 isnull() / 결측치의 합을 보여주게 하는 sum()을 붙여서 1이상이 나오면 결측치가 있고 0이면 없는 것이다.

 

payment_df.duplicated().sum() #중복값이 없는지 확인

order_items_df.duplicated().sum()

customer_df.duplicated().sum()  

order_df.duplicated().sum()  

products_df.duplicated().sum() 

# customer_df에서 3089개의 중복값 확인

 

tip. primry key는 테이블의 각 행을 고유하게 식별되는 데 사용

 

null값이 1개 이상인 전체 데이터를 보고싶다.

 

products_df['missing_count'] = products_df.isnull().sum(axis=1)

# ['missing_count']를 추가하여 몇개의 결측치가 있는지 저장할 공간 생성

# products_df.isnull().sum( )결측치의 개수를 찾는방법

# (axis=1) 축설정

 

이후에는 각각의 행에 대해서 결측치가 몇개인지 알려주는 열이 생겨서 필터링 필요

 

filtered_df = products_df[products_df['missing_count'] > 0 ]

# products_df에 조건 걸기

# [products_df['missing_count'] > 0 ]는 products_df['missing_count']가 0개 초과하는 것만 보겟다는 조건

=> 결측치가 있던 애들이 하나의 행에서 발생한 것을 볼 수 있다.

 

merge() 진행 전에 중복값을 제거 해야한다.

 

customer_df = customer_df.drop_duplicates() #중복값 제거

 

merged_ order_id  = pd.merge(orders_df, payments_df, how = 'left', on = 'order_id' )

# orders_dfpayments_df는 order_id로 연결 되어있으니 order_id를 기준으로 merged_ order_id을 left 조인 할거다.
merged_ customer_id = pd.merge( merged_ order_id , customers_df, how = 'left', on = 'customer_id')

# merged_ order_id  customer_id 를 기준으로 customers_df 와 결합해 merged_ customer_id  생성
merged_ order_id2 = pd.merge( merged_ customer_id , order_items_df, how = 'left', on = 'order_id')

# merged_ customer_id  order_id 를 기준으로 order_items_df 결합해  merged_ order_id2 생성
merged_ product_id = pd.merge( merged_ order_id2 , products_df, how = 'left', on = 'product_id')

#   merged_ order_id2product_id 를 기준으로 products_df 결합해 merged_ product_id  생성

 

merged_product_id.duplicated().sum() # merged_product_id의 중복값 확인

 

merged_product_id.isnull().sum()

#결측치 확인 됨(원래 결측치가 있었어서 여전히 존재하는데 merge결과에 따라 급격히 늘어남)

 

merged_product_id = merged.dropna() #결측치 제거

 

 

1. 파생변수 만들기

1) merged['product_volume'] = merged['product_length_cm'] + merged['product_height_cm'] + merged['product_width_cm']

 

merged['product_volume']  # product_volume라는 새로운 변수 생성

merged['product_length_cm'] + merged['product_height_cm'] + merged['product_width_cm']

#product요소들의 합을 값으로 준다

 

2) merged['delivered_time'] = merged['order_delivered_timestamp'] - merged['order_purchase_timestamp'] 

(타입변환을 진행해 주었기 때문에 같은 타입끼리 연산이 가능)

 

2. 타입 변환(object타입을date타입으로 변환 할건데 지원하는 연산이 한정적 / 다르기 때문에변환한다)

merged['order_delivered_timestamp'] = pd.to_datetime(merged['order_delivered_timestamp'])

 

merged['order_delivered_timestamp'] #바꾼 요소의 변수이름 설정

pd.to_datetime() #datetime으로 데이터타입 변환 함수

['order_delivered_timestamp']  #바꿀 요소 선택

 

3. 이상치 찾기

tip. 찾기전에 데이터의 특성을 분석하고 논리에 맞는 기준을 세우고 그후에 그 기준대로 이상치를 처리해야지 의미있는 데이터가 나온다.

주의. 이상치를 처리 후 결측치 처리와 결측치 처리 후 이상치 처리는 값이 다르다.

1.IQR사용(숫자형 데이터 사용 가능)

1) IQR방법을 일괄로 사용하려면 코드적으로 접근하는게 좋다.

 

4. 인코딩

 

1).nunique()

각각의 컬럼에 유일값이 몇개있는지 확인하는 함수

merged_product_id.nunique()

카테고리형 변수는 한정 된 범위를 갖는다고해서 항상 카테고리라고 하지 않는다.

범주에 속하는 경우 카테고리 변수라고 하기 때문에 적절한 인코딩 방법을 사용해야한다.

빈도수에 따라 인코딩해야한다. (변수가 name이면 다양한  이름이 올것이기 때문에 딥러닝의 인베딩 개념을 사용하면 좋다.)

 

2) 원핫 인코딩(새로운 컬럼 생성)

pd.get_dummies()

 

merged = pd.get_dummies(merged, columns = ['payment_type'])

pd.get_dummies( merged_product_id ) #새로운 columns 생성 위치  merged_product_id 지정

columns = ['payment_type'] #지정한 columns에만 새로운 columns 생성

주의. 컬럼이 너무 많은 곳에 사용하면 컬럼이 너무 많아져 좋지않은 영향을 준다.

 

5. 스케일링(이해가 안되요)

from sklearn.preprocessing import StandardScaler

 

scaler = StandardScaler()

 

scaler_data = scaler.fit_transform(merged_product_id)=>안된다면 타입이 안맞아서 그럴 수 있다.

타입캐스팅이 발생할 수 있기 때문에 항상 주의 해야한다.

 

 

 

정확성 검증

(테이블 단위로 info(), .isnull().sum(), .duplicated().sum()으로 검증이 가능 하다.

해당 과정은 전반적인 전처리를 진행하는 것)

 

가격과 배송비의 합을 order_item_id 단위로 더해서 order_id행에 추가해야한다.

order_id에 item 단위로 각각의 price를 구해줄것이다.

그런데  order_item_id가 같더라도 payment가 여러번 나뉜 경우 행이 쪼개져있기 때문에 이경우에는 order_id와 order_item_id로 그룹화 하는데 price의 평균을 구해 줄것이다. 그래서 order_item_id로 모든 값을 하나로 묶어 줄 것이다.

 

1. order_id와 order_item_id의 price와 shipping_charges의 평균

grouped_1 = merged_product_id.groupby(by = ['order_id', 'order_item_id']).agg({"price":'mean','shipping_charges':'mean'})

 

grouped_1 #그룹화할 변수 생성

merged_product_id.groupby() # merged_product_id에 groupby()함수 사용

by = ['order_id', 'order_item_id'] #그룹화할 요소 선택

agg() #연산 함수 사용를 포함 시키기 위한 함수

{"price":'mean','shipping_charges':'mean'} # price와 shipping_charges에 각각 평균함수 사용 지정

 

2. order_id의 price와 shipping_charges가 궁금하다.

grouped_1 = grouped_1.groupby(by = ['order_id']).agg({'price':'sum', 'shipping_charges':'sum'})

 

grouped_1 #그룹화할 변수 생성

grouped_1.groupby() #  grouped_1에 groupby() 함수사용

by = ['order_id'] #그룹화할 요소 선택

agg() #연산 함수 사용를 포함 시키기 위한 함수

{'price':'sum', 'shipping_charges':'sum'} # price와 shipping_charges가 하나하나 독립 된 값이여서 'SUM'사용

 

3. order_id와 payment_sequential의 payment_value평균

grouped_2 = merged_product_id.groupby(by = ['order_id', 'payment_sequential']).agg({'payment_value':'mean'})

 

4. order_id의 payment_value

grouped_2 = grouped_2.groupby(by = ['order_id']).agg({'payment_value':'sum'})

 

 

merge()전/후 그리고 데이터 처리 전/후 비교를 꼭 해보아야한다.

 


특강( 학습법 마음가짐 

 

 

중요한건 협업과 기술적 고민

문제해결능력/커뮤니케이션 능력

로직과 코드 의도생각하기

구현하는 기술,스택에 목적과 근거 가지기

더 좋은 방법이 있는지 고민하기 AZURE

예쁘게말하기

명확하게 말하기 = 두괄식

근거를 바탕으로 소통하기

 

9to9활용법

개념 구조 => 실습으로 익히기강의는 복습 필요 => 키워드 필기해서 찾아보는게 필수(전체를 파악하기 힘드니)과제는 완성하지 못해도 피드백받으면서 부족한 부분 채우고 최종적으론 기한 지키기질문과 공유는 필수

 

질문

구글링할때 유용한 확장팩 notion clipper, liner, openai

협업에 대해 => 회사마다 프로젝트마다 다르다.

변수 컨벤션, git.branch등 여러방법을 사전에 정한다.

redis, github살펴보기 (github가 뭐지)개발자로 처음 들어가게 되면 코드로 과제를 받고 수행하는 것 부터 시작할 것이다.

잘못된 코드 컨벤션 고치냐 안고치고 잘못된 변수명을 통일되게 쓰냐

 


 

회고

6-1

멀티인덱스 데이터 접근

 xs()를 이용해서 서울에 대한 데이터만을 가져왔는데 그 과정에서 어떤게 추출되고 제거 되었는지 이해가 안간다.

=재수강

 

6-3

판다스 실습

파일의 위치를 파이썬 파일과 같은 경로에 두어야한다.

나는 파이썬 파일이 어디에 생성 되는 건지 찾지 못해 애먹었지만 

jupyter home에서 파일을 열어 위치를 찾고 다운받은 파일을 옮겨 주었다.

 

그러면 쥬피터나 vscode에서 파이썬 파일을 만들 때 위치 지정을 해줄수있나?(파일들이 지저분함)

오후 회의때 질문 해보기(질문 찾지 못해서 질문 못함 다음 수업 회의때나 튜터님에게 질문 해보기)

 

primry key란

테이블의 각 행을 고유하게 식별되는 데 사용

 

직접 진행한 이상치 찾기 실습은 오류가 낫음

=코드 해석해보기 

 

스케일링 이해가 안감

=재수강 or 질문해보기

 

  • 배열연산 및 브로드 캐스팅
  • 불러온 데이터 미리보기 및 확인 10:50

 

2-3

배열연산 및 브로드 캐스팅

 

numpy를 활용하기 전에 반드시 문서를 확이해보아야한다.

np.subtract() 빼기연산

 

multiply() 곱셈 연산 (행열 연산이 아니라 요소 하나하나 곱하는 것)

 

floor_divide() 두 배열의 요소별 나눗셈 하고 소수점 이하는 버려준다.

 

mod() 요소별 나눗셈의 나머지를 반환

 

prod() 누적 곱셈

 

cumsum() 누적 덧셈 (값으로 나온 위치들 마다 앞에 위치한 요소들의 합이다.)

 

mean 평균

 

median 중간 요소들의 평균 

arr1([1,2,3,4,5,6])일땐 3가4의 평균인 3.5가 값으로 나온다.

 

std() 표준편차

 

var() 분산계산

분산이란? 관측값에서 평균 을 뺀 값을 제곱 하고, 그것을 모두 더한 후 전체 개수로 나눠서 구한다.

분산 계산은 어디에서 사용하지?

 

argmin/max 최소값/최대값의 위치 찾기

 

ptp 최대 최소의 차이가 어느정도인지 범주를 보여줌

 

exp 자연지수 계산

 

dot() 행열의 정곱

 


 

3-1

판다스 사용!

만일 현재 디렉토리에 csv파일을 저장해놓았다면

df = pd.read_csv("파일이름.txt")

csv란 데이터를 텍스트 형식으로 저장하는 데 사용하는 쉬운 파일 형식입니다.

 

데이터 불러오기

df.head() 데이터의 간략한 부분만 볼 수 있게한다.

df.tail() 뒤에서부터도 볼 수 있다.

df.sample() 랜덤하게 개수 지정한 만큼 골 수 있다.

df.info() 데이터 셋에 대한 전반적인 정보를 볼 수 있다.

df.describe() 기초 통계량의 정보를 볼 수 있다.

df.dtypes 컬럼별 타입을 확인할 수 있다.

df.columns 컬럼 이름을 확인할 수 있다.

for i in df.columns:
    print(df[i])  #각 컬럼에 대해 개별적인 접근이 가능하다.

df.index 데이터의 인덱스를 확인할 수 있다.

인덱스란? DB내부의 저장된 데이터의 주소 

 

 

1) 주요 옵션 sep, header

sep: 구분자를 지정합니다. 기본값은 ,입니다.

header: 헤더 행을 지정합니다. 기본값은 첫 번째 행(0)입니다.

만약 데이터가 탭으로 구분되어 있다면?

이스케이프 시퀀시(escape sequence)로 표현한다.

sheet_name : 읽고자 하는 시트 이름 또는 번호를 지정합니다. 기본값은 첫 번째 시트(0)입니다.

 

escape sequence란?

프로그래밍 언어 특성상 표현할 수 없는 기능, 문자를 표현해준다.

( \ )백슬래시와 함께 쓰여 설정 된 효과를 출력한다.

 

백슬래시는 \와 원화표시 왜 2개로 나오는가?

폰트의 우선순위로 보이는게 다르다. 한국어 우선이면 원화 영어 우선이면'\'이다.

 

2) URL로 데이터 불러오기

url = '<https://example.com/data.csv>' df_csv_url = pd.read_csv(url)

 

3) Excle파일 불러오기

df_excel = pd.read_excel('data.xlsx')

 

4) URL에서 Excel파일 불러오기

url = '<https://example.com/data.xlsx>'

 

5) Jason파일 불러오기

웹에서 자주 사용하는 데이터 형식.

df_json = pd.read_json('data.json')

jason은 테이블 형식이 아니라서 pandas에서 쓰려면

파씽, 플래튼 작업이 필요 함

 

6) cvs파일로 저장하기

df.to_csv('data.csv', index=False)

df.to_Excel

df.to_Jason

주의. URL을 지정하면 안된다.

 

7) 데이터 베이스 연결하기

conn = sqlite3.connect('database.db')

연결 후 sql테이블로 저장

df.to_sql('table_name', conn, if_exists='replace', index=False)

연결종료

conn.close()

 

 


 

3-2

불러온 데이터 미리보기 및 확인

 

튿정열에 대한 정보 

print(df['나이'].describe())

 

첫번째 행 확인

print(df.loc[0])

print(df.loc[0], name) 척번째행의 이름 확인

print(df.iloc[0, 1]) 첫 번째 행의 두 번째 열 데이터 조회

 

+ Recent posts