1. 데이터 이상치 알아보기- boxplot
박스 플롯(boxplot)은 데이터의 분포를 시각적으로 나타내는 통계 그래픽스입니다. 주로 데이터의 중앙값, 사분위수, 이상치 등을 파악하는 데 사용됩니다. 박스 플롯은 다음과 같은 구성 요소로 이루어져 있습니다.
- 상자(Box): 데이터의 사분위수(Q1, Q2, Q3)를 나타냅니다. 상자의 아래 경계는 Q1이고1/4분위수 즉 25%값을 나타냅니다. 상자 내부의 가로선은 중앙값(Q2) (50%)입니다. 상자의 윗 경계는 Q3 (75%)입니다.
- 수염(Whisker): 상자 위아래로 나타나는 선분으로, 전체 데이터 범위를 나타냅니다. 일반적으로 최대값과 최소값 중 1.5배 사분위 범위를 벗어나는 값은 이상치로 표시되며, 수염은 그 범위 내의 최대값과 최소값을 나타냅니다.
- 이상치(Outliers): 수염 바깥에 위치한 점들로, 일반적인 데이터 패턴에서 벗어난 극단값을 나타냅니다.
박스 플롯은 주로 데이터의 중심 경향과 분포를 파악하는 데 사용되며, 다수의 그룹 간 비교에도 유용합니다. 이를 통해 데이터의 대략적인 형태를 빠르게 파악할 수 있습니다.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 코랩에서 ANSI인코딩을 알맞게 가져와주는 방법 encoding='ms949'
# 다른 이름 저장으로 인코딩을 UTF-8로 바꿔도 상관없음.
park = pd.read_csv('/content/drive/MyDrive/KDT/데이터분석/데이터/전국도시공원표준데이터.csv', encoding='ms949')
park.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 18137 entries, 0 to 18136
Data columns (total 20 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 관리번호 18137 non-null object
1 공원명 18137 non-null object
2 공원구분 18137 non-null object
3 소재지도로명주소 8039 non-null object
4 소재지지번주소 17158 non-null object
5 위도 18137 non-null float64
6 경도 18137 non-null float64
7 공원면적 18137 non-null float64
8 공원보유시설(운동시설) 4845 non-null object
9 공원보유시설(유희시설) 6964 non-null object
10 공원보유시설(편익시설) 5084 non-null object
11 공원보유시설(교양시설) 1160 non-null object
12 공원보유시설(기타시설) 3116 non-null object
13 지정고시일 15225 non-null object
14 관리기관명 17383 non-null object
15 전화번호 16957 non-null object
16 데이터기준일자 18137 non-null object
17 제공기관코드 18137 non-null object
18 제공기관명 18137 non-null object
19 Unnamed: 19 0 non-null float64
dtypes: float64(4), object(16)
memory usage: 2.8+ MB
park.drop(columns=['공원보유시설(운동시설)','공원보유시설(유희시설)','공원보유시설(편익시설)','공원보유시설(교양시설)',
'공원보유시설(기타시설)','지정고시일','관리기관명','Unnamed: 19'], inplace=True)
park.head()
sns.boxplot(y=park['위도'])
# Q3 - Q1을 이용해서 최소,최대값을 예측. 해당 범위를 벗어나면 이상치로 예측해볼 수 있음
sns.boxplot(y=park['경도'])
# 위도와 경도의 이상치로 판별되는 데이터를 확인
park.loc[(park['위도']<32) | (park['경도']>132)]
park.plot.scatter(x='경도', y='위도',figsize = (8,10), grid=True)
park = park.loc[(park['위도']>=32) & (park['경도']<=132)]
>> 이상치가 아닌 데이터들로만 재저장.
2. 따릉이 실시간 예제.
import requests
import folium
import json
from pandas.io.json import json_normalize
import warnings
warnings.filterwarnings('ignore') # 필요없는 경고가 뜨는것을 방지
- import json: json을 파이썬의 딕셔너리처럼 이용하게 해주는 모듈
- json_normalize : 딕셔너리처럼 바꾼 json을 pandas의 데이터 프레임으로 변경해줌
targetSite = 'https://www.bikeseoul.com/app/station/getStationRealtimeStatus.do'
request = requests.post(targetSite, data={'stationGrpSeq':'ALL'})
# data={'stationGrpSeq':'ALL'} : API 명세서에서 요청하는 항목
print(request) // <Response [200]>
print(request.text)
// {"stationImgPath":"/nas_link/spb/attachFiles/file_admin/basePath","appUserSessionVO":{"regDttm":null,
"orgType":null,"snsId":null,"viewFlg":"list","usrBirthDate":null,"sexCd":null,"rentEncPwd":null,
"telecomClsCd":null,"authCiVal":null,"authClsCd":null,"mbTelNo":null,....}
# json.loads(): json 타입의 문자열 데이터를 파이썬에서 처리할 수 있도록 변환(딕셔너리로 변환)
bike_json = json.loads(request.text)
print(bike_json)
// {'stationImgPath': '/nas_link/spb/attachFiles/file_admin/basePath', 'appUserSessionVO': {'regDttm': None,
'orgType': None, 'snsId': None, 'viewFlg': 'list', 'usrBirthDate': None,...}
print(type(bike_json)) // <class 'dict'>
bike_df = json_normalize(bike_json, 'realtimeList')
# json_normalize(): 딕셔너리 타입의 데이터를 판다스 데이터프레임으로 변환
# 안에 정보들중에 realtimeList 리스트만 데이터 프레임으로 만들겠다.
bike_df
bike_df.columns
Index(['stationImgFileName', 'stationId', 'stationName', 'stationLongitude',
'stationLatitude', 'rackTotCnt', 'parkingBikeTotCnt',
'parkingQRBikeCnt', 'parkingELECBikeCnt', 'stationSeCd', 'mode'],
dtype='object')
stationImgFileName : 대여소 사진
stationId : 고유한 대여소 번호
stationName : 대여소 이름
stationLongitude : 대여소 경도
stationLatitude : 대여소 위도
rackTotCnt : 주차 가능한 전체 자전거 대수
parkingBikeTotCnt : 주차된 따릉이 총 대수
parkingQRBikeCnt : 주차된 따릉이 QR형 총 대수
parkingELECBikeCnt : 주차된 새싹 따릉이 총 대수
bike_df_map = bike_df[['stationName', 'stationLongitude', 'stationLatitude',
'rackTotCnt', 'parkingBikeTotCnt', 'parkingQRBikeCnt',
'parkingELECBikeCnt']]
bike_df_map
bike_df_map.dtypes
# json이었던 것을 받았기 때문에 전부 문자열
stationName object
stationLongitude object
stationLatitude object
rackTotCnt object
parkingBikeTotCnt object
parkingQRBikeCnt object
parkingELECBikeCnt object
dtype: object
# 위도, 경도 -> float로 변환
# 주차 할 수 있는 자전거 대수, 주차된 자전거 총 대수, 주차된 QR 자전거 총 대수, 주차된 새싹 자전거 총 대수 - >int
# 전체 주차된 총 대수[total] = 자전거 + QR 자전거 + 새싹 자전거
bike_df_map['stationLongitude'] = bike_df_map['stationLongitude'].astype(float)
bike_df_map['stationLatitude'] = bike_df_map['stationLatitude'].astype(float)
bike_df_map['rackTotCnt'] = bike_df_map['rackTotCnt'].astype(int)
bike_df_map['parkingBikeTotCnt'] = bike_df_map['parkingBikeTotCnt'].astype(int)
bike_df_map['parkingQRBikeCnt'] = bike_df_map['parkingQRBikeCnt'].astype(int)
bike_df_map['parkingELECBikeCnt']= bike_df_map['parkingELECBikeCnt'].astype(int)
print(bike_df_map.dtypes)
stationName object
stationLongitude float64
stationLatitude float64
rackTotCnt int64
parkingBikeTotCnt int64
parkingQRBikeCnt int64
parkingELECBikeCnt int64
dtype: object
bike_df_map['total'] = bike_df_map['parkingBikeTotCnt'] + bike_df_map['parkingQRBikeCnt']
+ bike_df_map['parkingELECBikeCnt']
bike_df_map.shape
// (2724, 8)
문제. 따릉이 모든 데이터를 지도에 표기하기 (팝업: 대여소 이름 일반: -대, QR: -대, 새싹: -대, 총: -대)
bike_map = folium.Map(location=[bike_df_map['stationLatitude'].mean(), bike_df_map['stationLongitude'].mean()], zoom_start=12)
for index, data in bike_df_map.iterrows():
string = '{} 일반:{}대, QR:{}대, 새싹:{}대, 총:{}대'.format(data['stationName'],
data['parkingBikeTotCnt'],
data['parkingQRBikeCnt'],
data['parkingELECBikeCnt'],
data['total'])
popup = folium.Popup(string, max_width=600)
folium.Marker(location=[data['stationLatitude'], data['stationLongitude']],
popup=popup).add_to(bike_map)
bike_map
✔️ iterrows()는 Pandas 데이터프레임의 각 행을 반복적으로 접근하기 위한 함수입니다. 이 함수를 사용하여 데이터프레임의 각 행에 대한 인덱스와 데이터를 제공받을 수 있습니다. 한 가지 유의해야 할 점은 iterrows()는 행 단위로 데이터프레임을 순회하면서 각 행을 시리즈(Series) 객체로 반환합니다. 따라서 data['stationName'], data['parkingBikeTotCnt'] 등과 같이 시리즈의 특정 열에 접근할 수 있습니다.
'데이터 분석' 카테고리의 다른 글
상권별 업종 밀집 통계 예제 (0) | 2023.12.23 |
---|---|
가상 쇼핑몰 데이터 예제 (0) | 2023.12.16 |
Matplotlib (0) | 2023.12.10 |
판다스3 (0) | 2023.12.08 |
판다스2 (0) | 2023.12.08 |