데이터 전처리 ( 이상치, 중복 데이터, 문자 데이터 )
이상치
• 다른 데이터보다 아주 작거나 큰 값을 말한다
• 데이터를 분석할 때 이상치는 의사결정에 영향을 미칠 수 있다
• 그러므로 이상치는 제거하거나 치환처리한다
이상치 데이터 처리
2. 이상치.html
0.32MB
2. 이상치.ipynb
0.05MB
이상치 데이터¶
- 이상치
- IQR의 1.5배 또는 3배의 차이가 나면 이상치라고 표현한다
- 다른 데이터보다 아주 작거나 큰 값을 말한다
- 데이터를 분석할 때 이상치는 의사결정에 영향을 미칠 수 있다.
- 이상치 처리
- 제거
- 오타, 오류, 비상식적 값들은 단순히 제거한다
- 치환
- 평균, 최빈값, 중앙값(중위수)
- 제거
- 이상치 구하기
- 1/4 분위값 25%, 2/4 분위값 중앙값(median), 3/4 분위값 75%
- IQR = Q3(3사분위) - Q1(1사분위)
- 최대 이상치 = Q3(3사분위) + IQR * 1.5(3.0)
- 최저 이상치 = Q1(1사분위) - IQR * 1.5(3.0)
![No description has been provided for this image](../images/4분위수.png)
In [ ]:
In [2]:
import pandas as pd
In [10]:
# 가상의 데이터임
# food_a, food_b, food_c 는 음식점이라고 가정
# 각 값들은 배달 소요시간을 의미
df = pd.read_csv("../data_set/2.데이터 클린징/food.csv")
df.head()
Out[10]:
food_a | food_b | food_c | |
---|---|---|---|
0 | 20 | 5 | 5 |
1 | 21 | 6 | 5 |
2 | 23 | 11 | 5 |
3 | 22 | 13 | 12 |
4 | 26 | 15 | 10 |
In [6]:
df.mean()
Out[6]:
food_a 47.407407 food_b 51.037037 food_c 42.407407 dtype: float64
In [17]:
# 기초 통계 값을 제공
df.describe()
# mean : 평균 값
# std : 표준 편차
# min : 최소 값
# max : 최대 값
# 50% 값 : 중위수 ( 중앙값 )
# 25% 값 : 그래프의 Q1 값
# 75% 값 : 그래프의 Q3 값
Out[17]:
food_a | food_b | food_c | |
---|---|---|---|
count | 27.000000 | 27.000000 | 27.000000 |
mean | 47.407407 | 51.037037 | 42.407407 |
std | 20.267935 | 110.789295 | 64.268822 |
min | 20.000000 | 5.000000 | 5.000000 |
25% | 38.000000 | 20.000000 | 20.000000 |
50% | 46.000000 | 30.000000 | 31.000000 |
75% | 57.000000 | 41.500000 | 45.500000 |
max | 120.000000 | 600.000000 | 350.000000 |
In [13]:
import numpy as np
test_median = [1,2,3,4,5,6,7,8,9,1000];
print('평균 : ', np.mean(test_median))
print('중위수(중앙 값) : ', np.median(test_median))
평균 : 104.5 중위수(중앙 값) : 5.5
In [16]:
a_m = np.median( df['food_a'] )
b_m = np.median( df['food_b'] )
c_m = np.median( df['food_c'] )
print("a의 중위수 : ", a_m)
print("b의 중위수 : ", b_m)
print("c의 중위수 : ", c_m)
a의 중위수 : 46.0 b의 중위수 : 30.0 c의 중위수 : 31.0
In [24]:
# 그래프로 표현해주는 matpolotlib.pyplot
# 출력되는 120 의 값이 이상치이고
# 80 이 최대 이상치, 20 이 최소 이상치, 노란선이 median(중위수)
# 사각형의 윗선이 Q3, 사각형의 아랫선이 Q1
# 사각형 위의 선은 최대 이상치
# 사각형 아래 선은 최소 이상치
import matplotlib.pyplot as plt
plt.boxplot(df['food_a'])
plt.show()
In [23]:
# 15와 -4 에 해당하는 값이 각각 이상치로 출력되며
# 중위 값은 노란 선
# 사각형의 윗선이 Q3, 아랫선이 Q1
# 사각형 위의 선은 최대 이상치
# 사각형 아래 선은 최소 이상치
test_median = [-4,2,3,4,5,6,7,8,9,15]
df_test = pd.DataFrame(test_median)
plt.boxplot( df_test[0] )
plt.show()
In [33]:
df_test.describe()
Out[33]:
0 | |
---|---|
count | 10.000000 |
mean | 5.500000 |
std | 4.972145 |
min | -4.000000 |
25% | 3.250000 |
50% | 5.500000 |
75% | 7.750000 |
max | 15.000000 |
In [30]:
# 25% 에 해당하는 값을 가져온다 ( Q1 지점 )
q1 = df_test.describe().loc['25%']
In [31]:
# 75% 에 해당하는 값을 가져온다 ( Q3 지점 )
q3 = df_test.describe().loc['75%']
In [32]:
q1, q3
Out[32]:
(0 3.25 Name: 25%, dtype: float64, 0 7.75 Name: 75%, dtype: float64)
In [36]:
# iqr 값은 q3 - q1
iqr = q3 - q1
# 최소 이상치 구하기
lower = q3 - iqr * 1.5
# 최대 이상치 구하기
upper = q1 + iqr * 1.5
iqr, lower, upper
# lower(최소 이상치) 미만 값과 upper(최대 이상치) 초과 값을
# 이상치로 판단하여 치환 혹은 삭제를 진행한다
Out[36]:
(0 4.5 dtype: float64, 0 1.0 dtype: float64, 0 10.0 dtype: float64)
In [42]:
# lower(최소 이상치) 보다 크거나 같으면 True 출력
# false 면 이상치
df_test >= lower
Out[42]:
0 | |
---|---|
0 | False |
1 | True |
2 | True |
3 | True |
4 | True |
5 | True |
6 | True |
7 | True |
8 | True |
9 | True |
In [41]:
# upper(최대 이상치) 보다 작거나 같으면 True 출력
# false 면 이상치
df_test <= upper
Out[41]:
0 | |
---|---|
0 | True |
1 | True |
2 | True |
3 | True |
4 | True |
5 | True |
6 | True |
7 | True |
8 | True |
9 | False |
In [50]:
# True 인 데이터들만 가져오겠다
# 이상치를 제외한 데이터들을 가져온다
df_test = df_test[(df_test >= lower) & (df_test <= upper)]
df_test
Out[50]:
0 | |
---|---|
0 | NaN |
1 | 2.0 |
2 | 3.0 |
3 | 4.0 |
4 | 5.0 |
5 | 6.0 |
6 | 7.0 |
7 | 8.0 |
8 | 9.0 |
9 | NaN |
In [55]:
# NaN 의 값을 중위수(중앙값) 으로 변경 후 저장
df_test.replace(to_replace = np.nan, value=df_test.describe().loc['50%'], inplace=True)
df_test
Out[55]:
0 | |
---|---|
0 | 5.5 |
1 | 2.0 |
2 | 3.0 |
3 | 4.0 |
4 | 5.0 |
5 | 6.0 |
6 | 7.0 |
7 | 8.0 |
8 | 9.0 |
9 | 5.5 |
In [58]:
# 그래프로 출력 ( 이상치가 없어졌음 )
plt.boxplot( df_test )
plt.show()
중복 데이터 처리
3. 중복데이터.html
0.27MB
3. 중복데이터.ipynb
0.01MB
In [1]:
import pandas as pd
In [2]:
df = pd.read_csv("../data_set/2.데이터 클린징/test1.csv")
df
Out[2]:
c1 | c2 | c3 | |
---|---|---|---|
0 | a | 1 | 1 |
1 | a | 1 | 1 |
2 | b | 1 | 2 |
3 | a | 2 | 2 |
4 | b | 2 | 2 |
5 | a | 1 | 1 |
In [4]:
# 중복 값이 True 로 처리된다
df.duplicated()
Out[4]:
0 False 1 True 2 False 3 False 4 False 5 True dtype: bool
In [9]:
# 중복 데이터의 갯수 구하기
df.duplicated().sum()
Out[9]:
0
In [8]:
# 중복 데이터 삭제
df.drop_duplicates(inplace=True)
df
Out[8]:
c1 | c2 | c3 | |
---|---|---|---|
0 | a | 1 | 1 |
2 | b | 1 | 2 |
3 | a | 2 | 2 |
4 | b | 2 | 2 |
In [7]:
df.duplicated().sum()
Out[7]:
0
In [12]:
# reset_index(drop=True) 는 index 를 재정의해준다
# 위에서 중복데이터를 삭제해 index 에 빈 값이 생긴걸
# 순서대로 다시 정렬해준다
df.reset_index(drop=True)
Out[12]:
c1 | c2 | c3 | |
---|---|---|---|
0 | a | 1 | 1 |
1 | b | 1 | 2 |
2 | a | 2 | 2 |
3 | b | 2 | 2 |
문자 데이터 처리
4. 문자 데이터.html
0.29MB
4. 문자 데이터.ipynb
0.03MB
문자 데이터¶
- 문자형 데이터
- 사이킷런은 문자열 값을 입력 값으로 처리 하지 않기 때문에 숫자 형으로 변환해야 한다.
LabelEncder¶
- 문자를 숫자로 변환해주는 기능
- .fit(값) : 변경하고자 하는 문자열 등록 기능
- .transform(값) : fit으로 등록한 문자열을 적용해준다
- .fit_transform : fit과 transform의 두가지 기능을 합친 기능
- .inverse_transform(값) : 변환된 숫자를 원래 값(문자)으로 표현해준다
- .classes_ : 숫자로 변환된 문자를 표현해 준다. 표현된 값은 0번째 번호부터 순차적으로 나오게 된다
In [1]:
import pandas as pd
df = pd.read_csv("../data_set/2.데이터 클린징/test2.csv")
df
Out[1]:
name | color | |
---|---|---|
0 | apple | red |
1 | banana | yellow |
2 | cherry | red |
3 | durian | green |
In [7]:
# sklearn.preprocessing 의 LabelEncoder 클래스를 import
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
# LabelEncoder 에 name 을 학습시킨 뒤
le.fit(df['name'])
# transform 을 통해 문자를 숫자로 학습한 값을 다시 df['name'] 으로
# 대입한다
df['name'] = le.transform(df['name'])
df
Out[7]:
name | color | |
---|---|---|
0 | 0 | red |
1 | 1 | yellow |
2 | 2 | red |
3 | 3 | green |
In [10]:
# fit_transform() 으로 한꺼번에 처리할 수도 있다
# color 의 문자 값을 학습시켜 숫자로 변환한뒤
# c-1 컬럼을 생성하여 넣어준 것
df['c-1'] = le.fit_transform(df['color'])
df
Out[10]:
name | color | c-1 | |
---|---|---|---|
0 | 0 | red | 1 |
1 | 1 | yellow | 2 |
2 | 2 | red | 1 |
3 | 3 | green | 0 |
In [9]:
df['color'].unique(), df['c-1'].unique()
Out[9]:
(array(['red', 'yellow', 'green'], dtype=object), array([1, 2, 0]))
In [13]:
# 직접 red 를 10 으로, yellow 를 20 으로, green 을 30으로 지정
item = {'red':10, 'yellow':20, 'green':30}
df['c-2'] = df['color'].map(item)
df
Out[13]:
name | color | c-1 | c-2 | |
---|---|---|---|---|
0 | 0 | red | 1 | 10 |
1 | 1 | yellow | 2 | 20 |
2 | 2 | red | 1 | 10 |
3 | 3 | green | 0 | 30 |
In [ ]:
In [ ]:
In [15]:
# 새로운 Dataset 추가
df=pd.DataFrame({
'id':[302,504,708,103,343,565],
'name':['Watch','Camera','Phone','Shoes','Laptop','Bed'],
'cost':["300","400","350","100","1000","400"],
'flt':["30.1","40.1","35.1","10.1","10.1","40.1"]
})
df
Out[15]:
id | name | cost | flt | |
---|---|---|---|---|
0 | 302 | Watch | 300 | 30.1 |
1 | 504 | Camera | 400 | 40.1 |
2 | 708 | Phone | 350 | 35.1 |
3 | 103 | Shoes | 100 | 10.1 |
4 | 343 | Laptop | 1000 | 10.1 |
5 | 565 | Bed | 400 | 40.1 |
In [16]:
# 원본 데이터를 복제하여 df_copy 에 저장
df_copy = df.copy()
In [19]:
# 데이터 타입을 확인
# cost 가 눈에 보이는 값은 숫자이지만 문자형태로 저장되어 있음
# flt 도 동일
df_copy.dtypes
Out[19]:
id int64 name object cost object flt object dtype: object
In [21]:
# to_numeric() 으로 정수 형태로 변환한 뒤
# 다시 저장하여 타입 확인
df_copy['cost'] = pd.to_numeric(df_copy['cost'])
df_copy.dtypes
Out[21]:
id int64 name object cost int64 flt object dtype: object
In [23]:
# to_numeric() 으로 실수(float) 형태로 변환한 뒤
# 다시 저장하여 타입 확인
df_copy['flt'] = pd.to_numeric(df_copy['flt'])
df_copy.dtypes
Out[23]:
id int64 name object cost int64 flt float64 dtype: object
In [ ]:
In [ ]:
In [25]:
# 원본 데이터를 복제하여 df_copy 에 저장
df_copy = df.copy()
df_copy.dtypes
Out[25]:
id int64 name object cost object flt object dtype: object
In [27]:
# astype 을 사용하여 자료형을 변환할 수도 있다
df_copy['flt'] = df_copy['flt'].astype(float)
df_copy['cost'] = df_copy['cost'].astype(int)
df_copy.dtypes
Out[27]:
id int64 name object cost int32 flt float64 dtype: object
In [ ]:
In [ ]:
- apply : 모든 값들을 한번에 연산할 때 사용
In [29]:
# 원본 데이터를 복제하여 df_copy 에 저장
df_copy = df.copy()
df_copy.dtypes
Out[29]:
id int64 name object cost object flt object dtype: object
In [31]:
# 한번에 지정한 모든 컬럼의 데이터를 형변환
df_copy[['cost','flt']] = df_copy[['cost','flt']].apply(pd.to_numeric)
df_copy.dtypes
Out[31]:
id int64 name object cost int64 flt float64 dtype: object
In [32]:
# 새로운 Dataset 추가
data = {'A':[1, 2, 3], 'B':[4, 5, 6], 'C':[7, 8, 9] }
df = pd.DataFrame(data)
df
Out[32]:
A | B | C | |
---|---|---|---|
0 | 1 | 4 | 7 |
1 | 2 | 5 | 8 |
2 | 3 | 6 | 9 |
In [34]:
import numpy as np
# 모든 합을 구해준다
np.sum( df ), np.sum(df['A'])
Out[34]:
(A 6 B 15 C 24 dtype: int64, 6)
In [35]:
df.sum(), df['B'].sum()
Out[35]:
(A 6 B 15 C 24 dtype: int64, 15)
In [37]:
# apply 는 모든 값들을 한번에 처리할 때 사용한다
df.apply( np.sum )
Out[37]:
A 6 B 15 C 24 dtype: int64
728x90
'BE > 머신러닝(ML)' 카테고리의 다른 글
[머신러닝] 데이터 전처리 ( 시계열 ) (0) | 2024.05.23 |
---|---|
[머신러닝] 데이터 전처리 ( 원 핫 인코딩 ) (0) | 2024.05.23 |
[머신러닝] 모델 생성 및 평가 (0) | 2024.05.23 |
[머신러닝] 데이터 전처리( 결측값 대체, 치환, 삭제 ) (1) | 2024.05.22 |
[머신러닝] Jupyter Notebook(Anaconda3) 설치 및 데이터 처리(pandas) 기본 코드 (1) | 2024.05.22 |