개발은 처음이라 개발새발

누락 데이터 치환하기 2 [python/pandas] 본문

파이썬/판다스

누락 데이터 치환하기 2 [python/pandas]

leon_choi 2022. 7. 29. 12:00
반응형

https://data-so-hard.tistory.com/34

 

누락 데이터 치환하기1 [python/pandas]

이번 시간은 누락 데이터를 제거하는 것이 아니라 치환하는 작업을 진행하겠습니다. 데이터 분석의 품질을 높이기 위해서는 결측치가 많은 데이터를 제거하는 것도 방법이지만 데이터의 양이

data-so-hard.tistory.com

지난 편에서는 fillna() 함수를 통해 평균 수치를 결측치에 삽입하는 것을 진행해봤습니다. 오늘은 좀 더 디테일하게 평균 데이터를 삽입해보려고 하는데요. 우선 판다스호의 데이터를 살펴보겠습니다. 

 

판다스호 데이터

데이터를 보면 성인 컬럼에 man, woman, child 총 3가지의 값이 있는데요. 이럴 경우 단순 평균을 넣을 경우 데이터의 질이 나빠질 수 있습니다. 특히, child는 어린이기 때문에 평균 나이인 25세를 넣을 경우 어린이의 평균 데이터라고 보기 힘들겠죠? 그래서 이번에는 groupby를 통해 man, woman,child 각각의 평균 나이를 구하고 각각의 빈곳에 데이터를 집어 넣어보도록 하겠습니다. 

 

우선 성인 컬럼의 값별로 평균을 구하기 위해서는 groupby의 주체가 df['성인']이 되어야 합니다. 그리고 이들의 평균 즉, mean()함수를 적용해야 하고 성인 컬럼의 값별 평균 나이를 구해야 하니 옆에 ['나이'] 컬럼을 적어야 합니다. 코딩을 적고 결과를 보겠습니다. 

 

import pandas as pd
import numpy as np

df= pd.read_excel("판다스호.xlsx", sheet_name="Sheet1")

print(df)
print('\n')

#groupby로 성인별 평균 나이 구하기
avg = round(df.groupby(['성인']).mean()['나이'],0)
print(avg)
print('\n')
     예약  현장구매 구역  방호수      성별     성인    나이  파티예약
0     0     1  A  101    male    man  35.0     0
1     1     0  B  203  female  woman  18.0     1
2     1     0  C  111    male  child   NaN     1
3     1     0  A  101    male  child   NaN     1
4     1     0  A  101  female  child   6.0     1
..   ..   ... ..  ...     ...    ...   ...   ...
114   1     0  C  101    male  child   8.0     1
115   1     0  A  203  female  child   9.0     1
116   1     0  B  111  female  child   6.0     1
117   1     0  C  101  female  child   6.0     1
118   1     0  A  101    male    man  38.0     1

[119 rows x 8 columns]




성인
child     7.0
man      38.0
woman    37.0
Name: 나이, dtype: float64

결과를 보면 child는 7, man 38, woman 37로 나옵니다. 남성이나 여성은 모르겠는데 child는 7인 것을 보면 확실히 전체 평균인 25를 넣으면 데이터가 많이 변질됐겠군요. 자, 이제 각 항목의 평균 나이를 구했으니 맞춤별로 데이터를 넣어보겠습니다. 그렇게 하기 위해서는 반복문과 조건문을 섞어서 알고리즘을 짜면 되는데요. 그전에 NaN값을 대체해야 하는데요. 그때는 replace()함수를 사용해 NaN값을 대체하면 됩니다. 저는 NaN을 0으로 대체해 보겠습니다. 

 

그리고 반복문을 써야 하는데요. 인덱스의 번호 별로 확인을해야 하기 때문에 범위는 df의 길이를 사용해야 합니다. 그리고 NaN값을 0으로 대체했으니 조건문에는 df['성인'] == 'man', df['성인'] == 'woman',df['성인'] == 'child'일 때 그리고 df['나이'] == 0일 때를 조건으로 하여야 합니다. 그렇다면 평균 나이는 어떻게 넣어야 할까요? 그때는 df.at 매소드를 사용해 "df.at[i, '나이'] = 넣을 데이터"를 통해 성인별 평균 나이를 넣으면 됩니다. 

 

이제 마지막으로 avg 변수를 통해 얻은 각각의 평균 나이 값은 어떻게 표출해야 할까인데요. 직접 7.0, 38.0, 37.0을 넣을 수 있지만 그렇게 하면 의미가 없죠. 숫자를 직접 넣지 않고 할 수 있는 방법은 iloc를 통해 각각 인덱스 번호에 맞춰 넣으면 됩니다. 즉, child가 제일 첫번째니까 child의 나이는 avg.iloc[0]이 되겠죠. 자 이제 모든 방법을 알아봤으니 코드를 적고 결과를 보겠습니다.

import pandas as pd
import numpy as np

df= pd.read_excel("판다스호.xlsx", sheet_name="Sheet1")

print(df)
print('\n')

#groupby로 성인별 평균 나이 구하기
avg = round(df.groupby(['성인']).mean()['나이'],0)
print(avg)
print('\n')

#nan으로 처리된 나이 값을 0으로 대체하기
df['나이'].replace(np.nan, 0, inplace=True)

for i in range(len(df)):
    
    if df.iloc[i]['성인'] == "child":
        if df.iloc[i]['나이'] == 0.0:
            df.at[i, '나이'] = avg.iloc[0]
    
    elif df.iloc[i]['성인'] == "man":
        if df.iloc[i]['나이'] == 0.0:
            df.at[i, '나이'] = avg.iloc[1]
    
    elif df.iloc[i]['성인'] == "woman":
        if df.iloc[i]['나이'] == 0.0:
            df.at[i, '나이'] = avg.iloc[2]
    
    
print(df.head(30))
    예약  현장구매 구역  방호수      성별     성인    나이  파티예약
0    0     1  A  101    male    man  35.0     0
1    1     0  B  203  female  woman  18.0     1
2    1     0  C  111    male  child   7.0     1
3    1     0  A  101    male  child   7.0     1
4    1     0  A  101  female  child   6.0     1
5    1     0  A  311    male    man  40.0     1
6    1     0  C  303  female  woman  37.0     1
7    0     1  A  311  female  woman  31.0     0
8    0     1  A  311  female  woman  37.0     0
9    0     1  B  107  female  woman  33.0     0
10   1     0  B  101  female  woman  66.0     1
11   0     1  C  106    male    man  38.0     0
12   1     0  A  208    male    man  38.0     1
13   0     1  C  301  female  woman  23.0     0
14   1     0  A  302    male  child   8.0     1
15   1     0  B  206  female  child  10.0     1
16   0     1  A  105    male    man  55.0     0
17   1     0  A  104    male  child   7.0     1
18   1     0  B  305    male  child   7.0     1
19   1     0  C  101  female  woman  45.0     1
20   1     0  A  203  female  child   7.0     1
21   1     0  C  111    male    man  21.0     1
22   1     0  C  101    male    man  22.0     1
23   0     1  A  101  female  woman  37.0     0
24   0     1  B  311    male  child   9.0     0
25   0     1  C  303  female  child   9.0     0
26   1     0  A  311  female  child   7.0     1
27   0     1  A  311  female  child   8.0     0
28   1     0  A  107    male    man  48.0     1
29   0     1  C  101    male    man  38.0     0

네 이렇게 어린이, 남자, 여자의 평균 나이가 맞게 잘 들어간 것을 확인할 수 있습니다. 

반응형