[천재교육] 프로젝트 기반 빅데이터 서비스 개발자 양성 과정 9기
학습일 : 2024.07.19
📕 학습 목록
- 데이터 분석 시작하기
- 데이터 불러오기
- 데이터 확인하기
- 범주형 자료
- 수치형 자료
- 데이터 선택하기
- 데이터 조작하기
📗 기억할 내용
1) 데이터 분석 시작하기
① Numpy 란?
- 파이썬의 고성능 수치 계산 라이브러리
- ndarray : Numpy 배열
- Numpy 배열 생성 방법
import numpy as np
# 1차원 배열 생성
array_1d = np.array([1, 2, 3, 4, 5])
# 배열에 문자열이 있으면 모든 값을 문자열로 변환
# Numpy가 하나의 자료형만 허용하기 때문
array_1d_str = np.array([1, 2, 3, 4, "5"])
# 2차원 배열 생성
array_2d = np.array([[1, 2], [3, 4]])
# 0이 저장된 1차원 배열
zeros_array_1d = np.zeros(10)
# 0이 저장된 2차원 배열 (행 길이, 열 길이)
zeros_array_2d = np.zeros((4, 2))
# 1이 저장된 1차원 배열
ones_array_1d = np.ones(10)
# 특정 값이 저장된 2차원 배열
four_array_2d = np.full((3, 3), 4)
# 랜덤 값이 저장된 2차원 배열
random_array_2d = np.random.random((9, 9))
② Pandas 란?
- 파이썬 언어로 작성된 데이터를 분석•조작하기 위한 라이브러리
- 기본 데이터 구조(판다스 객체)
- Series 객체 : 1차원 배열과 유사. 인덱스를 가진 데이터의 열
- DataFrame 객체 : 2차원 테이블. 여러 열(Series)을 포함
- 데이터프레임 생성
import pandas as pd
# [1. 딕셔너리 활용]
# 열 이름과 데이터를 저장한 딕셔너리
data = {
"name": ["민수", "지연", "현우", "수진", "영호", "민지", "지훈", "혜진"],
"age": [16, 18, 17, 15, 35, 10, 39, 59],
}
# 데이터프레임 생성
df = pd.DataFrame(data)
# [2. 이차원 리스트 활용]
data = [
["민수", 16],
["지연", 18],
["현우", 17],
["수진", 15],
["영호", 35],
["민지", 10],
["지훈", 39],
["혜진", 59],
]
# 컬럼명 리스트
columns = ["name", "age"]
# 데이터프레임 생성
df = pd.DataFrame(data, columns=columns)
2) 데이터 불러오기
① 데이터 불러오기 함수
import pandas as pd
# [1. CSV 파일 불러오기]
df = pd.read_csv("경로/파일명.csv")'
# [2. Excel 파일 불러오기]
df = pd.read_excel("경로/파일명.xlsx", sheet_name="시트명")
# [3. JSON 파일 불러오기]
df = pd.read_json("경로/파일명.json")
② 데이터 내보내기 함수
import pandas as pd
# [1. CSV 파일 내보내기]
DataFrame.to_csv("파일명.csv")
# [2. Excel 파일 내보내기]
DataFrame.to_excel("파일명.xlsx")
# [3. JSON 파일 내보내기]
DataFrame.to_json("파일명.json")
3) 데이터 확인하기
① 데이터 살펴보기
- df.head() / df.tail() : 상위 / 하위 n개 행 미리보기
- df.shape : 데이터프레임 (행, 열) 수 반환
- df.dtypes : 각 열의 데이터 타입 반환
- df.info() : 데이터프레임's 열 / 열 별 데이터 타입 / 결측치가 아닌 값의 수 / ... 반환
- df.index : 데이터프레임's 인덱스 정보 반환
- df.columns : 데이터프레임's 열 정보 반환
② 데이터 정렬하기
- 값 기준 (열)정렬 : df.sort_values()
# 'Salary' 열을 기준으로 오름차순 정렬
sorted_df = df.sort_values(by='Salary')
# Office 기준 오름차순, Salary 기준 내림차순 정렬
# 두 개 이상의 열을 기준 정렬시, 먼저 적은 열 Office을 기준으로 오름차순 정렬 → 같은 값의 Office 내에서는 열 Salary 기준으로 내림차순 정렬
sorted_df = df.sort_values(by=['Office', 'Salary'], ascending=[True, False])
- 인덱스 기준 (행)정렬 : df.sort_index()
# 인덱스를 기준으로 오름차순 정렬 ≓ ignore_index = True
sorted_df = df.sort_index()
# 인덱스를 기준으로 내림차순 정렬
sorted_df = df.sort_index(ascending=False)
4) 범주형 데이터
① 범주형 데이터(Categorical Data) 란?
- 값이 몇 개의 카테고리(범주)로 구분되는 데이터
- 명목형 데이터 : 순서가 없는 범주형 데이터
- 순서형 데이터 : 순서가 있는 범주형 데이터
② 범주형 데이터 다루기
- unique() : 고유값 확인 - Series에서 중복을 제거한 고유값들의 배열을 반환
- DataFrame 객체에는 직접 사용x. 데이터프레임의 열에 대해 사용o
df['Brand'].unique()
# array(['Apple', 'Samsung', 'Xiaomi'], dtype=object)
- nunique() : 고유값 갯수 - 중복을 제거한 유니크한 값들의 개수를 반환
# 열 기준 유니크한 값의 개수
df.nunique()
'''
Brand 3
Model 7
Release 2
dtype: int64
'''
- value_counts() : 열 개수 카운트 - 각 열에서 유니크한 값이 나타나는 횟수를 반환
- DataFrame 객체에는 직접 사용x. 데이터프레임의 열에 대해 사용o
df['Brand'].value_counts()
'''
Samsung 3
Apple 2
Xiaomi 2
Name: Brand, dtype: int64
'''
- normalize = True 인자 : 각 값이 차지하고 있는 비중 확인
df['Brand'].value_counts(normalize=True)
'''
Samsung 0.428571
Apple 0.285714
Xiaomi 0.285714
Name: Brand, dtype: float64
'''
5) 수치형 변수
① 수치형 자료 구분
- 이산형 자료 : 값이 정수처럼 명확하게 구분된 자료
- 연속형 자료 : 특정 범위 내 연속적으로 나오는 자료
② 관련 메서드
- df.describe() : 데이터프레임의 각 열에대한 기술통계량(평균, 표준편차, 최소값, 최대값, 사분위수, ...)을 반환
- df.mean() / df.median() / df.mode() : 각 열의 평균값/중앙값/최빈값 반환
- df.var() / df.std() : 각 열의 분산 / 표준편차 반환
- df.max() / df.min() : 각 열의 최대값 / 최소값 반환
- df.quantile() : 각 열의 사분위수 반환 ex : df.quantile([0.25, 0.5, 0.75])
- df.sum() : 각 열의 합계 반환
- df.count() : 각 열의 개수 반환 (결측치 포함x)
- df.size() : 각 열의 개수 반환 (결측치 포함o)
6) 데이터 선택하기
- 인덱싱 / 필터링 : 데이터를 선택•조작하는데 사용되는 방법
① 인덱싱
- 데이터프레임•시리즈에서 특정 행•열을 선택
- 3가지 인덱싱 방법
- df[ ] : 단순 열 선택
- df.loc[ ] : 레이블(label) 기반 선택
- df.iloc[ ] : 인덱스(index) 기반 선택
② 필터링
- 데이터프레임에서 특정 조건을 만족하는 행을 선택
- 조건식 & 불리언 인덱싱 이용; 조건식 결과가 True인 행 선택
# [1. 단일 조건 필터링]
# 'Position'이 'Data Scientist'인 행만 필터링
filtered_df = df[df["Position"] == "Data Scientist"]
# 'Age' 열이 30 보다 큰 모든 행 선택
filtered_df = df[df['Age'] > 30]
# [2. 복수 조건 필터링]
# 복수의 조건을 & (AND)나 | (OR)을 사용하여 결합
# 'Position'이 'Data Scientist'인 행만 필터링
# 각 조건은 괄호로 묶음
# 'Position'이 'Software Engineer'이고 'Age'가 30 보다 큰 행 필터링
filtered_df = df[(df['Position'] == 'Software Engineer') & (df['Age'] > 30)]
# [3. isin 필터링]
# 'Position'이 'Data Scientist' 또는 'HR Specialist'인 행 필터링
filtered_df = df[df['Position'].isin(['Data Scientist', 'HR Specialist'])]
7) 데이터 조작하기
① 수정하기
- 값 수정 : loc / iloc
# 'A' 열의 첫 번째 행 값을 100으로 변경
df.loc[0, "A"] = 100
# 'B' 열의 모든 값을 10으로 변경
df.loc["B"] = 10
# 조건을 만족하는 셀만 선택하여 변경; 'A' 열의 값이 100 이상인 행의 'B'열 값을 50으로 변경
df.loc[df['A'] >= 100, 'B'] = 50
- 이름 수정 : rename()
# 딕셔너리 인자 사용; key(기존 이름) - value(새로운 이름)
# 열 이름 변경
df.rename(columns={'old_name': 'new_name'}, inplace=True)
df.rename({'old_name': 'new_name'}, axis=1)
# 인덱스 이름 변경
df.rename(index={'old_name': 'new_name'}, inplace=True)
df.rename({'old_name': 'new_name'}, axis=0)
- 자료형 수정 : astype()
# 새로운 데이터 타입을 인자로 받아 해당 열의 모든 값을 지정된 데이터 타입으로 변환
# 'A' 열을 float 자료형으로 변환
df["A"] = df["A"].astype(float)
# 'B' 열을 int 자료형으로 변환
df["B"] = df["B"].astype(int)
② 추가하기
- 새로운 행 추가
- loc 인덱싱 활용해서 직접 추가
- concat() 활용해서 데이터프레임 합치기
# [1. loc 인덱싱 활용해서 직접 추가]
# 새로운 행을 만들고, 데이터를 입력해서 행 추가
df = pd.DataFrame({"A": [1, 2, 3], "B": [4.5, 5.5, 6.4]})
df.loc[3, :] = [10, 10]
'''
A B
0 1.0 4.5
1 2.0 5.5
2 3.0 6.4
3 10.0 10.0
6 10.0 10.0
'''
# [2. concat 활용해서 데이터프레임 합치기]
# 두 개의 데이터프레임을 합쳐서 행을 추가
df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
new_df = pd.DataFrame({"A": [7], "B": [8]})
df = pd.concat([df, new_df], ignore_index=True)
'''
A B
0 1 4
1 2 5
2 3 6
3 7 8
'''
- 새로운 열 추가
- 직접 할당을 통해 새 열 추가
- 조건에 따른 새 열 추가
# [1. 직접 할당을 통한 새 열 추가]
# 새로운 열 이름을 지정하고, 값을 할당하여 추가함
df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
# 'C' 라는 새 열 추가하고 모든 값에 10 할당
df["C"] = 10
'''
A B C
0 1 4 10
1 2 5 10
2 3 6 10
'''
# [2. 조건에 따른 새 열 추가]
# 조건식을 사용, 새 열의 값을 조건에 따라 다르게 설정
# 새로운 E열을 생성, 조건을 만족함에 따라 값 대입
# 조건 : "A" 열의 값이 3이상 → 조건을 만족하면 'E' 열의 값 True, 아닐경우 False
df["E"] = df["A"] >= 3
'''
A B C E
0 1 4 10 False
1 2 5 10 False
2 3 6 10 True
'''
③ 삭제하기
- 데이터 삭제 : drop()
# 열 삭제
df.drop(columns=["열 이름1", "열 이름2", ...], inplace=True)
# 행 삭제
df.drop(index=["행 이름1", "행 이름2", ...], inplace=True)
# 조건부 행 삭제
# 1. 삭제 행 레이블 추출
label_drop = df[df["열 이름1"] < 30].index
# 2. 행 삭제 후 새로운 데이터프레임에 저장
df_dropped = df.drop(index=label_drop)
- 중복 데이터 확인 / 삭제 : duplicated() / drop_duplicated()
* 인자 keep을 통해 중복 행을 어떻게 식별할지 설정
- keep = 'first' : (기본값) 첫 번째 등장을 제외한 나머지 중복을 True로 표시 "첫 등장 값은 중복x 선언"
- keep = 'last' : 마지막 등장을 제외한 나머지 중복을 True 표시 "마지막 등장 값은 중복x 선언"
- keep = False : 모든 중복행을 True 표시 "모든 값을 중복o 선언"
# 중복 행 찾기; 중복 데이터 중 마지막 데이터를 제외하고 True 처리
df.duplicated(keep="last")
# 중복 행 선택해서 출력
print(df.loc[df.duplicated()])
# 중복 행 제거
df.drop_duplicates()
- 조건부 중복 삭제 : subset 인자 - 특정 열을 기준으로 중복 삭제
# '이름'과 '나이' 열을 기준으로 중복 제거
# 단, 중복 행 중 마지막 행을 유지
df.drop_duplicates(subset=['이름', '나이'], keep='last')
📘 코드 개선
[개선 전]
Q) 열 pclass 가 2 또는 3이고, survived 가 1인 모든 행을 출력하시오
# |(or) 과 &(and) 를 조합해서 코드를 작성함 filtering = ((df['pclass'] == 2) | (df['pclass'] == 3)) & (df['survived'] == 1) print(df[filtering])
survived pclass sex age sibsp parch fare embarked class \ 2 1 3 female 26.0 0 0 7.9250 S Third 8 1 3 female 27.0 0 2 11.1333 S Third 9 1 2 female 14.0 1 0 30.0708 C Second 10 1 3 female 4.0 1 1 16.7000 S Third 15 1 2 female 55.0 0 0 16.0000 S Second .. ... ... ... ... ... ... ... ... ... 866 1 2 female 27.0 1 0 13.8583 C Second 869 1 3 male 4.0 1 1 11.1333 S Third 874 1 2 female 28.0 1 0 24.0000 C Second 875 1 3 female 15.0 0 0 7.2250 C Third 880 1 2 female 25.0 0 1 26.0000 S Second who adult_male deck embark_town alive alone 2 woman False NaN Southampton yes True 8 woman False NaN Southampton yes False 9 child False NaN Cherbourg yes False 10 child False G Southampton yes False 15 woman False NaN Southampton yes True .. ... ... ... ... ... ... 866 woman False NaN Cherbourg yes False 869 child False NaN Southampton yes False 874 woman False NaN Cherbourg yes False 875 child False NaN Cherbourg yes True 880 woman False NaN Southampton yes False [206 rows x 15 columns]
[개선 후]
# isin() 메서드를 활용하여 코드 작성 filtering = (df["pclass"].isin([2, 3])) & (df["survived"] == 1) print(df[filtering])
survived pclass sex age sibsp parch fare embarked class \ 2 1 3 female 26.0 0 0 7.9250 S Third 8 1 3 female 27.0 0 2 11.1333 S Third 9 1 2 female 14.0 1 0 30.0708 C Second 10 1 3 female 4.0 1 1 16.7000 S Third 15 1 2 female 55.0 0 0 16.0000 S Second .. ... ... ... ... ... ... ... ... ... 866 1 2 female 27.0 1 0 13.8583 C Second 869 1 3 male 4.0 1 1 11.1333 S Third 874 1 2 female 28.0 1 0 24.0000 C Second 875 1 3 female 15.0 0 0 7.2250 C Third 880 1 2 female 25.0 0 1 26.0000 S Second who adult_male deck embark_town alive alone 2 woman False NaN Southampton yes True 8 woman False NaN Southampton yes False 9 child False NaN Cherbourg yes False 10 child False G Southampton yes False 15 woman False NaN Southampton yes True .. ... ... ... ... ... ... 866 woman False NaN Cherbourg yes False 869 child False NaN Southampton yes False 874 woman False NaN Cherbourg yes False 875 child False NaN Cherbourg yes True 880 woman False NaN Southampton yes False [206 rows x 15 columns] # (행, 열) 개수가 달라짐
📙 내일 일정
- 파이썬 데이터 전처리 복습
'TIL _Today I Learned > 2024.07' 카테고리의 다른 글
[DAY 9] Data Preprocessing, Data Visualization (0) | 2024.07.23 |
---|---|
[DAY 8] Data Manipulation, Data Preprocessing (0) | 2024.07.22 |
[DAY 6] Python Crawling (0) | 2024.07.18 |
[DAY 5] Python Crawling (0) | 2024.07.17 |
[DAY 4] Python Programming (0) | 2024.07.16 |