데이터 전처리 ( 결측값 대체, 치환, 삭제 )
결측 데이터 처리
결측치 확인 > 결측치 확인 후 대체 및 제거 > 결측치 반영 확인
( 데이터의 양이 많을 경우 결측치를 제거, 데이터의 양이 적을 경우 대체 )
In [1]:
import pandas as pd
In [31]:
df = pd.read_csv("../data_set/2.데이터 클린징/nan.csv")
df
# 데이터가 없는 경우 NaN 으로 처리됨
Out[31]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | NaN |
1 | 3 | 4 | 2 | NaN | NaN |
2 | 3 | 4 | 8 | 2.4 | NaN |
3 | 9 | 10 | 11 | NaN | NaN |
4 | 12 | 10 | 14 | 1.2 | NaN |
5 | 15 | 16 | 17 | NaN | 1.0 |
In [9]:
df.head(2)
Out[9]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | NaN |
1 | 3 | 4 | 2 | NaN | NaN |
In [10]:
df.tail(2)
Out[10]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
4 | 12 | 10 | 14 | 1.2 | NaN |
5 | 15 | 16 | 17 | NaN | 1.0 |
In [14]:
# 데이터가 결측치인 경우 True 를 출력
df.isnull()
Out[14]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | False | False | False | False | True |
1 | False | False | False | True | True |
2 | False | False | False | False | True |
3 | False | False | False | True | True |
4 | False | False | False | False | True |
5 | False | False | False | True | False |
In [13]:
# 컬럼 별 결측치 확인
df.isnull().sum()
Out[13]:
data1 0 data2 0 data3 0 nan_1 3 nan_2 5 dtype: int64
In [15]:
df.shape
Out[15]:
(6, 5)
In [18]:
# isnull 과 반대인 notnull
# 결측치는 true, 값이 있는 경우 false
df.notnull()
Out[18]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | True | True | True | True | False |
1 | True | True | True | False | False |
2 | True | True | True | True | False |
3 | True | True | True | False | False |
4 | True | True | True | True | False |
5 | True | True | True | False | True |
In [20]:
# 컬럼 별 결측치 확인
# isnull() 이 훨씬 직관적임!!!
df.notnull().sum()
Out[20]:
data1 6 data2 6 data3 6 nan_1 3 nan_2 1 dtype: int64
In [21]:
df.isnull().sum()
Out[21]:
data1 0 data2 0 data3 0 nan_1 3 nan_2 5 dtype: int64
In [ ]:
In [ ]:
In [22]:
df
Out[22]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | NaN |
1 | 3 | 4 | 2 | NaN | NaN |
2 | 3 | 4 | 8 | 2.4 | NaN |
3 | 9 | 10 | 11 | NaN | NaN |
4 | 12 | 10 | 14 | 1.2 | NaN |
5 | 15 | 16 | 17 | NaN | 1.0 |
In [23]:
# 결측치가 있는 값을 가진 행을 모두 삭제
df.dropna()
Out[23]:
data1 | data2 | data3 | nan_1 | nan_2 |
---|
In [24]:
# 결측치가 있는 열을 삭제
df.dropna( axis = 1 )
Out[24]:
data1 | data2 | data3 | |
---|---|---|---|
0 | 0 | 1 | 2 |
1 | 3 | 4 | 2 |
2 | 3 | 4 | 8 |
3 | 9 | 10 | 11 |
4 | 12 | 10 | 14 |
5 | 15 | 16 | 17 |
In [26]:
# nan_1 컬럼에 결측치가 있는 데이터만 출력
df[ df['nan_1'].isnull() ]
Out[26]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
1 | 3 | 4 | 2 | NaN | NaN |
3 | 9 | 10 | 11 | NaN | NaN |
5 | 15 | 16 | 17 | NaN | 1.0 |
In [28]:
# nan_1 컬럼에 결측치가 없는 데이터만 출력
df[ df['nan_1'].notnull() ]
Out[28]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | NaN |
2 | 3 | 4 | 8 | 2.4 | NaN |
4 | 12 | 10 | 14 | 1.2 | NaN |
In [32]:
# nan_1 에 해당하는 열이 삭제된다
del df['nan_1']
df
Out[32]:
data1 | data2 | data3 | nan_2 | |
---|---|---|---|---|
0 | 0 | 1 | 2 | NaN |
1 | 3 | 4 | 2 | NaN |
2 | 3 | 4 | 8 | NaN |
3 | 9 | 10 | 11 | NaN |
4 | 12 | 10 | 14 | NaN |
5 | 15 | 16 | 17 | 1.0 |
In [ ]:
In [ ]:
대체(치환)¶
- 0으로 치환 : fillna(0)
- 평균으로 치환 : fillna(df.mean())
- 중위수로 치환 : fillna(df.describe().loc['50%']) 또는 df.median()
- 중위수 또는 중앙값 이라고 표현한다.
- 예) {1,3,6,6,7,10,12,12,17} 7이 중간에 있기 때문에 중위수는 7이 된다
- 예) {1,3,6,6,12,17} : 중간값이 없으면 (6+6) / 2가 중간값(6)이 된다.
- 최빈값으로 치환 : df.value_counts() 또는 df.mode()
- 주어진 데이터 중 가장 자주 나오는 데이터
- 예) {1, 3, 6, 6, 6, 7, 7, 12, 12, 17} 최빈값은 6이된다
- 이전값 : 순차적으로 시작하여 현재값 다음 NaN값을 현재 값으로 변경 : fillna(method='pad')
- 다음값 : 역순으로 시작하여 현재 값을 다음 NaN값을 현재 값으로 변경 : fillna(method='bfill')
In [33]:
df = pd.read_csv("../data_set/2.데이터 클린징/nan.csv")
df
Out[33]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | NaN |
1 | 3 | 4 | 2 | NaN | NaN |
2 | 3 | 4 | 8 | 2.4 | NaN |
3 | 9 | 10 | 11 | NaN | NaN |
4 | 12 | 10 | 14 | 1.2 | NaN |
5 | 15 | 16 | 17 | NaN | 1.0 |
In [35]:
# 결측 값을 모두 0으로 변환
df.fillna(value=0)
Out[35]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | 0.0 |
1 | 3 | 4 | 2 | 0.0 | 0.0 |
2 | 3 | 4 | 8 | 2.4 | 0.0 |
3 | 9 | 10 | 11 | 0.0 | 0.0 |
4 | 12 | 10 | 14 | 1.2 | 0.0 |
5 | 15 | 16 | 17 | 0.0 | 1.0 |
In [38]:
# 평균값으로 치환
# df.mean() 이 평균을 구하는 코드이다
df.fillna(df.mean())
Out[38]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.700000 | 1.0 |
1 | 3 | 4 | 2 | 1.766667 | 1.0 |
2 | 3 | 4 | 8 | 2.400000 | 1.0 |
3 | 9 | 10 | 11 | 1.766667 | 1.0 |
4 | 12 | 10 | 14 | 1.200000 | 1.0 |
5 | 15 | 16 | 17 | 1.766667 | 1.0 |
In [39]:
# 중앙값, 최빈값 확인
data = {'v1':[12,12,17,1,3,6,6,7,10],
'v2':[1,3,6,6,6,7,7,12,12] }
df_test = pd.DataFrame(data)
df_test
Out[39]:
v1 | v2 | |
---|---|---|
0 | 12 | 1 |
1 | 12 | 3 |
2 | 17 | 6 |
3 | 1 | 6 |
4 | 3 | 6 |
5 | 6 | 7 |
6 | 6 | 7 |
7 | 7 | 12 |
8 | 10 | 12 |
In [44]:
# 중위 수를 구해준다 ( 자동으로 데이터를 정렬해서 구해준다 )
# 중위 수는 정렬했을 때 가운데 있는 값
# 만약 데이터의 갯수가 짝수인 경우 중앙에 위치한 2 수의 평균을 출력함
df_test.median()
Out[44]:
v1 7.0 v2 6.0 dtype: float64
In [43]:
# sort_values() 를 사용하면 정렬이 가능하다
df_test['v1'].sort_values()
Out[43]:
3 1 4 3 5 6 6 6 7 7 8 10 0 12 1 12 2 17 Name: v1, dtype: int64
In [46]:
# 최빈 값 구하기 ( 가장 많이 사용된 데이터를 출력 )
df_test.mode()
Out[46]:
v1 | v2 | |
---|---|---|
0 | 6 | 6.0 |
1 | 12 | NaN |
In [51]:
# 각 컬럼의 데이터 별로 몇 번씩 사용되었는지 value_counts() 로 확인
df_test['v2'].value_counts()
Out[51]:
v2 6 3 7 2 12 2 1 1 3 1 Name: count, dtype: int64
In [50]:
# 각 컬럼의 데이터 별로 몇 번씩 사용되었는지 value_counts() 로 확인
df_test['v1'].value_counts()
Out[50]:
v1 12 2 6 2 17 1 1 1 3 1 7 1 10 1 Name: count, dtype: int64
In [52]:
df
Out[52]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | NaN |
1 | 3 | 4 | 2 | NaN | NaN |
2 | 3 | 4 | 8 | 2.4 | NaN |
3 | 9 | 10 | 11 | NaN | NaN |
4 | 12 | 10 | 14 | 1.2 | NaN |
5 | 15 | 16 | 17 | NaN | 1.0 |
In [53]:
df.median()
Out[53]:
data1 6.0 data2 7.0 data3 9.5 nan_1 1.7 nan_2 1.0 dtype: float64
In [55]:
# 결측치를 중앙 값으로 치환
df.fillna(df.median())
Out[55]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | 1.0 |
1 | 3 | 4 | 2 | 1.7 | 1.0 |
2 | 3 | 4 | 8 | 2.4 | 1.0 |
3 | 9 | 10 | 11 | 1.7 | 1.0 |
4 | 12 | 10 | 14 | 1.2 | 1.0 |
5 | 15 | 16 | 17 | 1.7 | 1.0 |
In [57]:
# 최빈 값 구하기
df.mode()
Out[57]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 3.0 | 4.0 | 2.0 | 1.2 | 1.0 |
1 | NaN | 10.0 | NaN | 1.7 | NaN |
2 | NaN | NaN | NaN | 2.4 | NaN |
In [58]:
df.fillna(df.mode())
Out[58]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | 1.0 |
1 | 3 | 4 | 2 | 1.7 | NaN |
2 | 3 | 4 | 8 | 2.4 | NaN |
3 | 9 | 10 | 11 | NaN | NaN |
4 | 12 | 10 | 14 | 1.2 | NaN |
5 | 15 | 16 | 17 | NaN | 1.0 |
In [59]:
# 0번째 인덱스만 가져온다
df.mode().loc[0]
Out[59]:
data1 3.0 data2 4.0 data3 2.0 nan_1 1.2 nan_2 1.0 Name: 0, dtype: float64
In [61]:
# 최빈값으로 결측값을 치환
df.fillna(df.mode().loc[0])
Out[61]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | 1.0 |
1 | 3 | 4 | 2 | 1.2 | 1.0 |
2 | 3 | 4 | 8 | 2.4 | 1.0 |
3 | 9 | 10 | 11 | 1.2 | 1.0 |
4 | 12 | 10 | 14 | 1.2 | 1.0 |
5 | 15 | 16 | 17 | 1.2 | 1.0 |
In [62]:
df
Out[62]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | NaN |
1 | 3 | 4 | 2 | NaN | NaN |
2 | 3 | 4 | 8 | 2.4 | NaN |
3 | 9 | 10 | 11 | NaN | NaN |
4 | 12 | 10 | 14 | 1.2 | NaN |
5 | 15 | 16 | 17 | NaN | 1.0 |
In [64]:
# pad : 결측 데이터의 이전 값으로 치환
df.fillna( method = 'pad' )
C:\Users\user\AppData\Local\Temp\ipykernel_4076\4292871891.py:2: FutureWarning: DataFrame.fillna with 'method' is deprecated and will raise in a future version. Use obj.ffill() or obj.bfill() instead. df.fillna( method = 'pad' )
Out[64]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | NaN |
1 | 3 | 4 | 2 | 1.7 | NaN |
2 | 3 | 4 | 8 | 2.4 | NaN |
3 | 9 | 10 | 11 | 2.4 | NaN |
4 | 12 | 10 | 14 | 1.2 | NaN |
5 | 15 | 16 | 17 | 1.2 | 1.0 |
In [65]:
# pad : 결측 데이터의 다음 값으로 치환
df.fillna( method = 'bfill' )
C:\Users\user\AppData\Local\Temp\ipykernel_4076\1765903578.py:2: FutureWarning: DataFrame.fillna with 'method' is deprecated and will raise in a future version. Use obj.ffill() or obj.bfill() instead. df.fillna( method = 'bfill' )
Out[65]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | 1.0 |
1 | 3 | 4 | 2 | 2.4 | 1.0 |
2 | 3 | 4 | 8 | 2.4 | 1.0 |
3 | 9 | 10 | 11 | 1.2 | 1.0 |
4 | 12 | 10 | 14 | 1.2 | 1.0 |
5 | 15 | 16 | 17 | NaN | 1.0 |
In [66]:
# 유일한 값을 뽑아준다
df['nan_1'].unique()
Out[66]:
array([1.7, nan, 2.4, 1.2])
In [ ]:
In [ ]:
In [69]:
df
Out[69]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | NaN |
1 | 3 | 4 | 2 | NaN | NaN |
2 | 3 | 4 | 8 | 2.4 | NaN |
3 | 9 | 10 | 11 | NaN | NaN |
4 | 12 | 10 | 14 | 1.2 | NaN |
5 | 15 | 16 | 17 | NaN | 1.0 |
In [70]:
# 값이 2인 데이터를 200 으로 치환
df.replace(to_replace=2, value=200)
Out[70]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 200 | 1.7 | NaN |
1 | 3 | 4 | 200 | NaN | NaN |
2 | 3 | 4 | 8 | 2.4 | NaN |
3 | 9 | 10 | 11 | NaN | NaN |
4 | 12 | 10 | 14 | 1.2 | NaN |
5 | 15 | 16 | 17 | NaN | 1.0 |
In [72]:
# 값이 결측값인 데이터를 replace 를 사용하여 치환
# numpy 를 import 후 nan(결측값)을 확인하여 사용
import numpy as np
df.replace(to_replace=np.nan, value='변경')
Out[72]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | 변경 |
1 | 3 | 4 | 2 | 변경 | 변경 |
2 | 3 | 4 | 8 | 2.4 | 변경 |
3 | 9 | 10 | 11 | 변경 | 변경 |
4 | 12 | 10 | 14 | 1.2 | 변경 |
5 | 15 | 16 | 17 | 변경 | 1.0 |
In [75]:
# nan_1 의 nan 데이터만 치환
# inlplace 를 사용하여 자기 자신에게 반영 ( 변경 값을 다시 자기 자신에게 저장 )
import numpy as np
df.replace(to_replace={'nan_1':np.nan}, value='변경', inplace=True)
In [76]:
df
Out[76]:
data1 | data2 | data3 | nan_1 | nan_2 | |
---|---|---|---|---|---|
0 | 0 | 1 | 2 | 1.7 | NaN |
1 | 3 | 4 | 2 | 변경 | NaN |
2 | 3 | 4 | 8 | 2.4 | NaN |
3 | 9 | 10 | 11 | 변경 | NaN |
4 | 12 | 10 | 14 | 1.2 | NaN |
5 | 15 | 16 | 17 | 변경 | 1.0 |
In [78]:
# 서울시에서 제공한 데이터셋으로 연습
df = pd.read_csv('../data_set/2.데이터 클린징/bicycle.csv')
df.head()
Out[78]:
자전거번호 | 대여일시 | 대여소번호 | 대여소명 | 대여거치대 | 반납일시 | 반납대여소번호 | 반납대여소명 | 반납거치대 | 이용시간 | 이용거리 | 나이 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | SPB-23220 | 2019-11-01 8:48 | 646 | 장한평역 1번출구 (국민은행앞) | 3.0 | 2019-11-01 9:01 | 3 | 중랑센터 | 7.0 | 12.0 | 1100.0 | 50 |
1 | SPB-16216 | 2019-11-04 8:38 | 646 | 장한평역 1번출구 (국민은행앞) | 2.0 | 2019-11-04 8:56 | 3 | 중랑센터 | 2.0 | 7.0 | 1420.0 | 31 |
2 | SPB-21097 | 2019-11-04 8:46 | 646 | 장한평역 1번출구 (국민은행앞) | 1.0 | 2019-11-04 8:57 | 3 | 중랑센터 | 7.0 | 10.0 | NaN | 32 |
3 | SPB-22292 | 2019-11-05 8:34 | 646 | 장한평역 1번출구 (국민은행앞) | 1.0 | 2019-11-05 8:45 | 3 | 중랑센터 | NaN | 10.0 | 1380.0 | 21 |
4 | SPB-07935 | 2019-11-05 12:29 | 512 | 뚝섬역 1번 출구 옆 | 11.0 | 2019-11-05 12:39 | 3 | 중랑센터 | 7.0 | 10.0 | 1650.0 | 120 |
In [80]:
# 총 423 개의 데이터가 존재
# 12개의 컬럼 존재
df.shape
Out[80]:
(423, 12)
In [83]:
# 대여소 번호가 646인 데이터만 출력
df["대여소번호"] == 646
Out[83]:
0 True 1 True 2 True 3 True 4 False ... 418 False 419 False 420 False 421 False 422 False Name: 대여소번호, Length: 423, dtype: bool
In [82]:
df[df["대여소번호"] == 646]
Out[82]:
자전거번호 | 대여일시 | 대여소번호 | 대여소명 | 대여거치대 | 반납일시 | 반납대여소번호 | 반납대여소명 | 반납거치대 | 이용시간 | 이용거리 | 나이 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | SPB-23220 | 2019-11-01 8:48 | 646 | 장한평역 1번출구 (국민은행앞) | 3.0 | 2019-11-01 9:01 | 3 | 중랑센터 | 7.0 | 12.0 | 1100.0 | 50 |
1 | SPB-16216 | 2019-11-04 8:38 | 646 | 장한평역 1번출구 (국민은행앞) | 2.0 | 2019-11-04 8:56 | 3 | 중랑센터 | 2.0 | 7.0 | 1420.0 | 31 |
2 | SPB-21097 | 2019-11-04 8:46 | 646 | 장한평역 1번출구 (국민은행앞) | 1.0 | 2019-11-04 8:57 | 3 | 중랑센터 | 7.0 | 10.0 | NaN | 32 |
3 | SPB-22292 | 2019-11-05 8:34 | 646 | 장한평역 1번출구 (국민은행앞) | 1.0 | 2019-11-05 8:45 | 3 | 중랑센터 | NaN | 10.0 | 1380.0 | 21 |
5 | SPB-18401 | 2019-11-06 8:52 | 646 | 장한평역 1번출구 (국민은행앞) | 1.0 | 2019-11-06 9:09 | 3 | 중랑센터 | 7.0 | 11.0 | 1350.0 | 30 |
6 | SPB-18350 | 2019-11-06 8:35 | 646 | 장한평역 1번출구 (국민은행앞) | 1.0 | 2019-11-06 9:10 | 3 | 중랑센터 | 2.0 | 9.0 | 1390.0 | 26 |
8 | SPB-20220 | 2019-11-11 8:35 | 646 | 장한평역 1번출구 (국민은행앞) | 2.0 | 2019-11-11 8:42 | 3 | 중랑센터 | 2.0 | 6.0 | 1160.0 | 53 |
9 | SPB-20102 | 2019-11-11 9:45 | 646 | 장한평역 1번출구 (국민은행앞) | 8.0 | 2019-11-11 10:17 | 3 | 중랑센터 | 7.0 | 30.0 | 1060.0 | 54 |
10 | SPB-10000 | 2019-11-12 8:35 | 646 | 장한평역 1번출구 (국민은행앞) | 8.0 | 2019-11-12 8:44 | 3 | 중랑센터 | 2.0 | 8.0 | 1300.0 | 30 |
11 | SPB-20145 | 2019-11-13 8:30 | 646 | 장한평역 1번출구 (국민은행앞) | 9.0 | 2019-11-13 8:38 | 3 | 중랑센터 | 2.0 | NaN | 1060.0 | 34 |
12 | SPB-19057 | 2019-11-13 8:55 | 646 | 장한평역 1번출구 (국민은행앞) | 4.0 | 2019-11-13 9:08 | 3 | 중랑센터 | 7.0 | 11.0 | NaN | 57 |
13 | SPB-19645 | 2019-11-14 9:44 | 646 | 장한평역 1번출구 (국민은행앞) | NaN | 2019-11-14 10:01 | 3 | 중랑센터 | 7.0 | 16.0 | 1140.0 | 59 |
14 | SPB-21851 | 2019-11-14 9:33 | 646 | 장한평역 1번출구 (국민은행앞) | 10.0 | 2019-11-14 10:02 | 3 | 중랑센터 | 2.0 | 28.0 | 1220.0 | 51 |
15 | SPB-13973 | 2019-11-15 8:42 | 646 | 장한평역 1번출구 (국민은행앞) | 1.0 | 2019-11-15 8:50 | 3 | 중랑센터 | 2.0 | 6.0 | 1370.0 | 32 |
16 | SPB-22311 | 2019-11-18 8:32 | 646 | 장한평역 1번출구 (국민은행앞) | 6.0 | 2019-11-18 8:39 | 3 | 중랑센터 | 2.0 | NaN | 1350.0 | 31 |
17 | SPB-02270 | 2019-11-18 8:49 | 646 | 장한평역 1번출구 (국민은행앞) | 4.0 | 2019-11-18 9:01 | 3 | 중랑센터 | 7.0 | 11.0 | 1350.0 | 31 |
18 | SPB-23659 | 2019-11-21 8:36 | 646 | 장한평역 1번출구 (국민은행앞) | NaN | 2019-11-21 8:44 | 3 | 중랑센터 | 2.0 | 6.0 | 1130.0 | 33 |
19 | SPB-23497 | 2019-11-21 8:50 | 646 | 장한평역 1번출구 (국민은행앞) | 2.0 | 2019-11-21 9:04 | 3 | 중랑센터 | 7.0 | 13.0 | 1330.0 | 32 |
21 | SPB-21810 | 2019-11-25 8:41 | 646 | 장한평역 1번출구 (국민은행앞) | 5.0 | 2019-11-25 8:49 | 3 | 중랑센터 | 2.0 | 7.0 | 1310.0 | 50 |
22 | SPB-05857 | 2019-11-26 8:40 | 646 | 장한평역 1번출구 (국민은행앞) | 6.0 | 2019-11-26 8:48 | 3 | 중랑센터 | 2.0 | NaN | 1380.0 | 41 |
24 | SPB-20076 | 2019-11-28 8:37 | 646 | 장한평역 1번출구 (국민은행앞) | 6.0 | 2019-11-28 8:44 | 3 | 중랑센터 | 2.0 | 5.0 | 1070.0 | 51 |
In [84]:
df.loc[df["대여소번호"] == 646]
Out[84]:
자전거번호 | 대여일시 | 대여소번호 | 대여소명 | 대여거치대 | 반납일시 | 반납대여소번호 | 반납대여소명 | 반납거치대 | 이용시간 | 이용거리 | 나이 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | SPB-23220 | 2019-11-01 8:48 | 646 | 장한평역 1번출구 (국민은행앞) | 3.0 | 2019-11-01 9:01 | 3 | 중랑센터 | 7.0 | 12.0 | 1100.0 | 50 |
1 | SPB-16216 | 2019-11-04 8:38 | 646 | 장한평역 1번출구 (국민은행앞) | 2.0 | 2019-11-04 8:56 | 3 | 중랑센터 | 2.0 | 7.0 | 1420.0 | 31 |
2 | SPB-21097 | 2019-11-04 8:46 | 646 | 장한평역 1번출구 (국민은행앞) | 1.0 | 2019-11-04 8:57 | 3 | 중랑센터 | 7.0 | 10.0 | NaN | 32 |
3 | SPB-22292 | 2019-11-05 8:34 | 646 | 장한평역 1번출구 (국민은행앞) | 1.0 | 2019-11-05 8:45 | 3 | 중랑센터 | NaN | 10.0 | 1380.0 | 21 |
5 | SPB-18401 | 2019-11-06 8:52 | 646 | 장한평역 1번출구 (국민은행앞) | 1.0 | 2019-11-06 9:09 | 3 | 중랑센터 | 7.0 | 11.0 | 1350.0 | 30 |
6 | SPB-18350 | 2019-11-06 8:35 | 646 | 장한평역 1번출구 (국민은행앞) | 1.0 | 2019-11-06 9:10 | 3 | 중랑센터 | 2.0 | 9.0 | 1390.0 | 26 |
8 | SPB-20220 | 2019-11-11 8:35 | 646 | 장한평역 1번출구 (국민은행앞) | 2.0 | 2019-11-11 8:42 | 3 | 중랑센터 | 2.0 | 6.0 | 1160.0 | 53 |
9 | SPB-20102 | 2019-11-11 9:45 | 646 | 장한평역 1번출구 (국민은행앞) | 8.0 | 2019-11-11 10:17 | 3 | 중랑센터 | 7.0 | 30.0 | 1060.0 | 54 |
10 | SPB-10000 | 2019-11-12 8:35 | 646 | 장한평역 1번출구 (국민은행앞) | 8.0 | 2019-11-12 8:44 | 3 | 중랑센터 | 2.0 | 8.0 | 1300.0 | 30 |
11 | SPB-20145 | 2019-11-13 8:30 | 646 | 장한평역 1번출구 (국민은행앞) | 9.0 | 2019-11-13 8:38 | 3 | 중랑센터 | 2.0 | NaN | 1060.0 | 34 |
12 | SPB-19057 | 2019-11-13 8:55 | 646 | 장한평역 1번출구 (국민은행앞) | 4.0 | 2019-11-13 9:08 | 3 | 중랑센터 | 7.0 | 11.0 | NaN | 57 |
13 | SPB-19645 | 2019-11-14 9:44 | 646 | 장한평역 1번출구 (국민은행앞) | NaN | 2019-11-14 10:01 | 3 | 중랑센터 | 7.0 | 16.0 | 1140.0 | 59 |
14 | SPB-21851 | 2019-11-14 9:33 | 646 | 장한평역 1번출구 (국민은행앞) | 10.0 | 2019-11-14 10:02 | 3 | 중랑센터 | 2.0 | 28.0 | 1220.0 | 51 |
15 | SPB-13973 | 2019-11-15 8:42 | 646 | 장한평역 1번출구 (국민은행앞) | 1.0 | 2019-11-15 8:50 | 3 | 중랑센터 | 2.0 | 6.0 | 1370.0 | 32 |
16 | SPB-22311 | 2019-11-18 8:32 | 646 | 장한평역 1번출구 (국민은행앞) | 6.0 | 2019-11-18 8:39 | 3 | 중랑센터 | 2.0 | NaN | 1350.0 | 31 |
17 | SPB-02270 | 2019-11-18 8:49 | 646 | 장한평역 1번출구 (국민은행앞) | 4.0 | 2019-11-18 9:01 | 3 | 중랑센터 | 7.0 | 11.0 | 1350.0 | 31 |
18 | SPB-23659 | 2019-11-21 8:36 | 646 | 장한평역 1번출구 (국민은행앞) | NaN | 2019-11-21 8:44 | 3 | 중랑센터 | 2.0 | 6.0 | 1130.0 | 33 |
19 | SPB-23497 | 2019-11-21 8:50 | 646 | 장한평역 1번출구 (국민은행앞) | 2.0 | 2019-11-21 9:04 | 3 | 중랑센터 | 7.0 | 13.0 | 1330.0 | 32 |
21 | SPB-21810 | 2019-11-25 8:41 | 646 | 장한평역 1번출구 (국민은행앞) | 5.0 | 2019-11-25 8:49 | 3 | 중랑센터 | 2.0 | 7.0 | 1310.0 | 50 |
22 | SPB-05857 | 2019-11-26 8:40 | 646 | 장한평역 1번출구 (국민은행앞) | 6.0 | 2019-11-26 8:48 | 3 | 중랑센터 | 2.0 | NaN | 1380.0 | 41 |
24 | SPB-20076 | 2019-11-28 8:37 | 646 | 장한평역 1번출구 (국민은행앞) | 6.0 | 2019-11-28 8:44 | 3 | 중랑센터 | 2.0 | 5.0 | 1070.0 | 51 |
In [85]:
# 대여소번호가 646인 값들 중 대여거치대, 반납일시 column 만 출력
df.loc[df["대여소번호"] == 646, ['대여거치대', '반납일시']]
Out[85]:
대여거치대 | 반납일시 | |
---|---|---|
0 | 3.0 | 2019-11-01 9:01 |
1 | 2.0 | 2019-11-04 8:56 |
2 | 1.0 | 2019-11-04 8:57 |
3 | 1.0 | 2019-11-05 8:45 |
5 | 1.0 | 2019-11-06 9:09 |
6 | 1.0 | 2019-11-06 9:10 |
8 | 2.0 | 2019-11-11 8:42 |
9 | 8.0 | 2019-11-11 10:17 |
10 | 8.0 | 2019-11-12 8:44 |
11 | 9.0 | 2019-11-13 8:38 |
12 | 4.0 | 2019-11-13 9:08 |
13 | NaN | 2019-11-14 10:01 |
14 | 10.0 | 2019-11-14 10:02 |
15 | 1.0 | 2019-11-15 8:50 |
16 | 6.0 | 2019-11-18 8:39 |
17 | 4.0 | 2019-11-18 9:01 |
18 | NaN | 2019-11-21 8:44 |
19 | 2.0 | 2019-11-21 9:04 |
21 | 5.0 | 2019-11-25 8:49 |
22 | 6.0 | 2019-11-26 8:48 |
24 | 6.0 | 2019-11-28 8:44 |
In [87]:
# 대여소번호가 646인 데이터들 중 값이 빈 것들의 합
df.loc[df["대여소번호"] == 646].isnull().sum()
Out[87]:
자전거번호 0 대여일시 0 대여소번호 0 대여소명 0 대여거치대 2 반납일시 0 반납대여소번호 0 반납대여소명 0 반납거치대 1 이용시간 3 이용거리 2 나이 0 dtype: int64
In [90]:
df[df["대여소번호"] == 646]['이용거리'].fillna(789.789)
Out[90]:
0 1100.000 1 1420.000 2 789.789 3 1380.000 5 1350.000 6 1390.000 8 1160.000 9 1060.000 10 1300.000 11 1060.000 12 789.789 13 1140.000 14 1220.000 15 1370.000 16 1350.000 17 1350.000 18 1130.000 19 1330.000 21 1310.000 22 1380.000 24 1070.000 Name: 이용거리, dtype: float64
In [96]:
df.loc[df["대여소번호"] == 646 , '이용거리'].fillna(111.111)
Out[96]:
0 1100.000 1 1420.000 2 111.111 3 1380.000 5 1350.000 6 1390.000 8 1160.000 9 1060.000 10 1300.000 11 1060.000 12 111.111 13 1140.000 14 1220.000 15 1370.000 16 1350.000 17 1350.000 18 1130.000 19 1330.000 21 1310.000 22 1380.000 24 1070.000 Name: 이용거리, dtype: float64
In [98]:
# 결측 값을 반영
df.loc[df["대여소번호"] == 646, '이용거리'] = df.loc[df["대여소번호"] == 646 , '이용거리'].fillna(111.111)
df.loc[df["대여소번호"] == 646, '이용거리']
Out[98]:
0 1100.000 1 1420.000 2 111.111 3 1380.000 5 1350.000 6 1390.000 8 1160.000 9 1060.000 10 1300.000 11 1060.000 12 111.111 13 1140.000 14 1220.000 15 1370.000 16 1350.000 17 1350.000 18 1130.000 19 1330.000 21 1310.000 22 1380.000 24 1070.000 Name: 이용거리, dtype: float64
In [101]:
# df 내에 대여소 번호가 646인 데이터들 중 이용거리의 결측값이 있던 데이터들이
# 모두 치환되어 결측값이 존재하지 않게 됨
df.loc[df["대여소번호"] == 646].isnull().sum()
Out[101]:
자전거번호 0 대여일시 0 대여소번호 0 대여소명 0 대여거치대 2 반납일시 0 반납대여소번호 0 반납대여소명 0 반납거치대 1 이용시간 3 이용거리 0 나이 0 dtype: int64
실습 예제 1
예제 풀이 1
실습 예제 2
예제 풀이 2
4.Quiz-loan(결측값)-풀이.pdf
2.99MB
비밀번호 : 댓글
728x90
'BE > 머신러닝(ML)' 카테고리의 다른 글
[머신러닝] 데이터 전처리 ( 시계열 ) (0) | 2024.05.23 |
---|---|
[머신러닝] 데이터 전처리 ( 원 핫 인코딩 ) (0) | 2024.05.23 |
[머신러닝] 모델 생성 및 평가 (0) | 2024.05.23 |
[머신러닝] 데이터 전처리 ( 이상치, 중복 데이터, 문자 데이터 ) (0) | 2024.05.23 |
[머신러닝] Jupyter Notebook(Anaconda3) 설치 및 데이터 처리(pandas) 기본 코드 (1) | 2024.05.22 |