df1 = df[['sw']] # 표준화할 컬럼 따로 빼오기
# 주의 ! Dataframe 형태로 가져오기 위해서 [] 두번 묶어주기
scale_df = StandardScaler().fit_transform(df1) # 표준화
scale_df = pd.DataFrame(scale_df) # Dataframe 형태로 변환
merge_df = pd.concat([df1,scale_df], axis=1) # 비교해보기 위해 두 컬럼 붙이기
merge_df.columns = ['Shipping Weight', 'Z-Score'] # 컬럼 이름 수정
strange_df = merge_df[(merge_df['Z-Score']>3)|(merge_df['Z-Score']<-3)] # +- 3이상인 조건으로 이상치 선별
strange_df.count() # 최종 이상치 개수 구하기
IQR(Interquartile Range) ⭐️
데이터가 정규분포를 이루지 않을 때, 사분위값이 얼마야? (= 값이 최대/최소값 밖이야? 그럼 너 이상치야.)
IQR로이상치 구하기 흐름
df1 = df[['sw']] # 이상치 점검할 컬럼 따로 빼오기
# 주의 ! Dataframe 형태로 가져오기 위해서 [] 두번 묶어주기
def is_outlier(df1):
score = df1['sw']
if score > 7 + (1.5 * 6) or score < 1 - (1.5 * 6):
return '이상치'
else:
return '이상치아님' # 이상치 구하는 함수 (외울 필요 없음)
df1['이상치여부'] = df1.apply(is_outlier, axis=1) # 함수 돌린 값들을 수직으로 나열한 새로운 컬럼 생성
df1.groupby('이상치여부').count() # 최종 이상치 개수 구하기
Isolation Forest
머신러닝 기법으로 이상치 구할 때 필요한 기준 (컬럼)이 많을 때 사용
기준마다 트리형태로 표현 True/False
경로 길이를 0~1 사이로 산출
1에 가까우면 (너무 짧게 끝나면) 이상치로 판단
DBScan
밀도 기반
주로 지리, 이미지 데이터 분석에서 활용
흐름
특정 거리 내에 특정 개수의 다른 데이터가 있을 경우 핵심 포인트로 간주
핵심 포인트끼리 연결되어 군집 형성
그 군집에 포함되지 않으면 이상치로 판단
2-2. Pandas 개인과제 6번
문제 포인트
datetime의 형변환 time ver.
lambda 이용해서 컬럼 만들어주기
여러 조건을 lnline if 절 안에서 걸어주기 (elif 안 됨)
import pandas as pd
# string -> datetime 형변환
df['Dep_Time'] = pd.to_datetime(df['Dep_Time'], format = '%H:%M')
df['time_of_dep'] = df['Dep_Time'].apply(lambda x: '아침' if 5 <= x.hour < 12 \
else ('낮' if 12 <= x.hour < 18 \
else ('오후' if 18 <= x.hour < 24 \
else '밤')))
df.groupby('time_of_dep')['Airline'].count()
Q1. 아까 IQR이상치 구할 때 .apply(~~~ , axis=1) 했던 거 같아서 여기도 넣어줬는데 실행 안됨. 뺐더니 됨.
axis =1 안 써줘도 되는 이유?
✔︎ Series 형태일 때는 필요 없음 ✔︎ DataFrame 형태일 때는 필수
Q2. 다 하고 나서 제대로 값 들어갔는지 확인하려고 df[df['Dep_Time'].hour == 0] 했더니 에러가 났다.
.dt.hour 해주니까 정상적으로 실행됨! 왜 .dt 를 붙여줘야함??
✔︎ 가져오는 게 Series이고, 그 Series의 타입이 datetime일 때, 각 행을 개별적으로 가져옴 ✔︎ 따라서 df['Dep_Time']은 Series 이기 때문에 dt 넣어줘야 한다.
def solution(x, n):
answer = []
for i in range(x,(x*n)+x,x):
answer.append(i)
return answer
solution(0,7)