[KT 에이블스쿨 7기] 데이터 분석
KT 에이블스쿨 7기 DX 트랙에 기자단으로 신청하기도 하였고, 복습을 통한 역량을 강화, 습득을 목적으로 작성되었음을 알려드립니다.
그럼, 복습 Let's go
Numpy
Python에서 Numpy(Numerical Python)는 수치 계산을 위한 필수 라이브러리로, 배열 연산, 선형대수, 통계, 난수 생성 등 다양한 수학적 기능을 제공하며, 특히, 데이터 분석과 머신러닝에서 데이터를 효율적으로 처리하기 위해 필수적으로 사용
Numpy 배열 만들기① 리스트를 Numpy 배열로 변환
import numpy as np
# 리스트를 Numpy 배열로 변환
arr = np.array([1, 2, 3, 4, 5])
print(arr)
print(type(arr)) #<class 'numpy.ndarray'>
② 다양한 방법으로 배열 생성
(1) zeros() - 모든 요소가 0인 배열
zero_arr = np.zeros((3,4)) # 3행 4열 배열
print(zero_arr)
zero_arr.dtype
(2) ones () - 모든 요소가 1인 배열
one_arr = np.ones((2,3)) # 2행 3열 배열
print(one_arr)
(3) arange() - 특정 범위의 숫자로 배열 생성
arange() - 특정 범위의 숫자로 배열 생성
for i in range (1, 10, 2) :
print(!)
(4) random() - 난수 배열 생성
random_arr = np.random.rand(2, 3) # 2행 3열의 랜덤 값 배열 (0 ~ 1 사이)
print(random_arr)
주요 연산도 가능하다!
arr = np.array([[1,2,3], [4,5,6]])
print(arr.shape) # (2,3) -> 2행 3열
print(arr.size) # 6
※ Numpy 중요한 점
- Numpy는 데이터 분석과 과학 연산을 위한 필수 라이브러리
- 다차원 배열(ndarray)을 사용하여 리스트보다 빠른 연산 가능
- 벡터 연산, 선형대수, 난수 생성 등 다양한 기능 제공
- Pandas, Scikit-learn 등 다른 데이터 분석 라이브러리와 함께 사용
Pandas란?
Pandas는 데이터 분석과 데이터 조작을 위한 Python 라이브러리로 특히, 표 형태 (테이블)로 데이터를 다룰 때 가장 많이 사용되며, 엑셀(Excel)과 비슷한 방식으로 데이터를 다룰 수 있도록 도움을 준다.
Pandas의 핵심 데이터 구조
- Pandas에서는 데이터를 다루기 위해 두 가지 주요 데이터 구조를 제공합니다.
데이터 구조 | 설명 | 형태 |
Series (시리즈) |
1차원 데이터(한 열)를 저장하는 구조 | 리스트, 배열과 유사 |
DataFrame (데이터프레임) |
2차원 데이터 (행과 열이 있는 표 형태) |
액셀 표와 유사 |
※ Series(시리즈)란?
- 1차원 데이터 구조로, 리스트, 배열과 유사하지만 인덱스가 포함되어 있는 것이 특징
1) Series 생성하기
import pandas as pd
data = [10, 20, 30, 40, 50] # 리스트 데이터
series = pd.Series(data) # 시리즈 생성
print(series)
# 0 10
# 1 20
# 2 30
# 3 40
# 4 50
# dtype: int64
2) Series에서 인덱스(index) 지정하기
- Series는 기본적으로 숫자 인덱스 (0, 1, 2,,,,) 가 자동 할당되지만, 사용자가 원하는 문자 인덱스(이름)을 지정할 수 있음
data = [100, 200, 300]
index_labels = ["a", "b", "c"] #인덱스 라벨 지정
import pandas as pd
series = pd.Series(data, Index = index_lables)
print(series)
※ pandas.Series 구조
class pandas.Series(data=None, index=None, dtype=None, name=None, copy=None, fastpath=<no_default>)
pandas.Series — pandas 2.2.3 documentation
pandas.Series — pandas 2.2.3 documentation
Values must be hashable and have the same length as data. Non-unique index values are allowed. Will default to RangeIndex (0, 1, 2, …, n) if not provided. If data is dict-like and index is None, then the keys in the data are used as the index. If the ind
pandas.pydata.org
DataFrame(데이터프레임)이란?
행(Row)과 열(Column)로 구성된 2차원 데이터 구조로 엑셀 표와 비슷한 구조를 가지고 있으며, 여러 개의 Series(시리즈)가 합쳐진 형태
1) DataFrame 생성하기 (리스트 활용)
data = [
['John', 28, 'New York'],
['Anna', 24, 'Paris'],
['Peter', 35, 'Berlin'],
['Linda', 32, 'London'],
]
df = pd.DataFrame(data, columns = ['name', 'age', 'city'])
print(df)
2) DataFrame 생성하기 (딕셔너리 활용)
data = {
"이름" : ['John', 'Anna', 'Peter' 28, 'New York'],
"나이" : [28, 24, 21],
"학점" : ["A", "B", "C"]
}
df = pd.DataFrame(data)
print(df)
용어 | 설명 | 예시 |
행(Row) | 데이터의 한 줄 | df.loc[0] (첫 번째 행) |
열(Column) | 데이터의 한 개 속성 | df["이름"] (이름 열) |
인덱스 (index) | 각 행을 구분하는 고유한 값 | 기본값 : 0, 1, 2,,,, |
값 (Value) | 실제 데이터 값 | "John", 20, "A" |
# 특정 컬럼 (열) 가져오기
Print(df["이름"])
0 John
1 Anna
2 Peter
# 특정 행(ROW) 가져오기
print(df.loc[0]) # 인덱스 1번 행 가져오기
이름 Anna
나이 22
학점 B
# 여러 개의 행 가져오기
Print(df.loc[[0, 2]]) # 0번, 2번 행 가져오기
0 John 20 A
1 Peter 21 A
※ 특정 조건의 데이터 필터링
print(df[df["나이"]>= 20 ]) # 나이가 20인 이상인 데이터만 선택
이름 나이 학점
anna 22 b
peter 21 a
데이터 전처리
데이터 불러오기 : read_csv
데이터 저장하기 : to_csv()
import pandas as pd
# 파일 불러오기
df = pd.read_csv("./data/seoul_park.csv")
df
# 파일 저장하기 -> 이후 파일이 생성되었는지 확인해보세요.
df.to_csv("./data/test_csv")
데이터 살펴보기 : shape
- DataFrame에서 행의 갯구, 열의 갯수는 shape 메서드를 통해 확인 가능합니다.
df.shape # (행, 열)
(1086, 11)
데이터 살펴보기 : head(), tail()
데이터 정보 확인 : info()
- 데이터가 몇 개의 값을 가지는지, 어떤 자료형으로 저장되어있는지를 확인할 수 있습니다.
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 이름 5 non-null object
1 나이 5 non-null int64
2 도시 5 non-null object
dtypes: int64(1), object(2)
memory usage: 252.0+ bytes
데이터 숫자 세기 : value_counts()
- value_counts()를 활용하면 컬럼에 어떤 값들이 몇 개씩 존재하는지 확인 가능합니다.
print(df["이름"].value_counts())
이름
John 2
Anna 2
Peter 1
Name: count, dtype: int64
데이터 통계정보 보기 : describe()
- DataFrame에서 숫자형 변수의 기초 통계량을 확인
# df.astype() # 날씨, 유료합계, 어른, 청소년을 문자열에서 숫자형 float로 바꾸는 것
# object -. int / float
# 내장함수 -> 문자열 / srt.replace(전, 교체할 문자)
df = pd.read_csv('./data/seoul_park.csv')
# df['외국인'] = df['외국인'].str.replace(',', '')
# df['외국인'] = df['외국인'].str.replace('-', '0')
# df['외국인'] = pd.to_numeric(df['외국인'])
df.describe()
Pandas를 활용한 데이터 정제 : 중복 데이터 제거, 결측치 처리, 이상치 처리
중복 데이터 확인하기 : duplicated ()
import pandas as pd
# 예제 데이터 생성
data = {
"이름": ["John", "Anna", "John", "Peter", "Anna"],
"나이": [20, 25, 20, 30, 25],
"도시": ["서울", "부산", "서울", "대전", "부산"]
}
df = pd.DataFrame(data)
df
df.duplicated()
중복 데이터 제거하기 : drop_duplicates()
data = {
"이름": ["John", "Anna", "John", "Peter", "Anna"],
"나이": [20, 25, 20, 30, 25],
"도시": ["서울", "부산", "서울", "대전", "부산"]
}
df = pd.DataFrame(data)
df
df.drop_duplicates()
만약 특정 열을 기준으로 중복 데이터를 제거하고 싶다면 subset 옵션을 사용할 수 있습니다.
"이름"컬럼을 기준으로 중복 데이터를 제거합니다. 중복 데이터 중 가장 첫번째 데이터만 남깁니다.
df_clean = df.drop_duplicates(subset = ["나이"], keep = "first")
df_clean
결측치 확인 : isnull()
import pandas as pd
data = {
"이름": ["John", "Anna", "Peter", "Sue"],
"나이": [20, 25, None, 30], # 결측치 존재
"도시": ["서울", None, "대전", "부산"]
}
df = pd.DataFrame(data)
df
df.info()
df.isnull()
df.isnull().sum()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 이름 4 non-null object
1 나이 3 non-null float64
2 도시 3 non-null object
dtypes: float64(1), object(2)
memory usage: 228.0+ bytes
결측치 제거 : dropna()
display(df)
df_clean = df.dropna() # 결측치가 포함된 행 제거
display(df_clean)
#DataFrame.dropna(*, axis=0, how=<no_default>, thresh=<no_default>, subset=None, inplace=False, ignore_index=False)[source]
df_clean2 = df.dropna(axis=1) # 열을 제거하고 싶을 때
df_clean2
결측치를 특정 값으로 대체 : fillna()
data = {
"이름": ["John", "Anna", "Peter", "Sue"],
"나이": [20, 25, None, 30], # 결측치 존재
"도시": ["서울", None, "대전", "부산"]
}
#DataFrame.fillna(value=None, *, method=None, axis=None, inplace=False, limit=None, downcast=<no_default>)
df = pd.DataFrame(data)
df_city = df["도시"].fillna("알수없음") # 도시의 결측치를 "알수없음"으로 대체
df_city
df_age = df["나이"].fillna(df["나이"].mean()) # 나이를 평균값으로 채움
df_age
이상치 확인 : IQR 방법 사용
import numpy as np
import pandas as pd
data = {
"이름": ["John", "Anna", "Peter", "Sue", "Tedy"],
"나이": [20, 25, 30, 120, 23] # 120은 이상치
}
df = pd.DataFrame(data)
Q1과 Q3의 차이를 통해 계산해보기
np.percentile(df["나이"], 25)
import numpy as np
import pandas as pd
Q1 = np.percentile(df["나이"], 25)
Q3 = np.percentile(df["나이"], 75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
print(f"정상 기준 : {lower_bound} ~ {upper_bound}") # | 는 or, &는 and
df [ (df['나이'] < lower_bound ) | ( df['나이'] > upper_bound ) ]
위에서 구한 IQR 범위 내에 들어오는 데이터를 찾아 DataFrame을 추출한 후, 새로운 변수에 할당하기
df_clean = df[( df["나이"] >= lower_bound) & (df["나이"] <= upper_bound )]
df_clean