🐍Python/Pandas

[Python] 파이썬 νŒλ‹€μŠ€(Pandas) - NaN λΉ„μ–΄ μžˆλŠ” 데이터 λ‹€λ£¨λŠ” 방법

루리야ㅑ 2023. 11. 15. 09:44
λ°˜μ‘ν˜•

사진: Unsplash 의 Kelly Sikkema

NaNμ΄λž€?

NaN은 "Not a Number"의 μ•½μžλ‘œ, 결츑치(missing value)λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 데 μ‚¬μš©λ˜λŠ” νŠΉμˆ˜ν•œ 값이닀. 주둜 파이썬의 νŒλ‹€μŠ€μ™€ 같은 데이터 뢄석 λ„κ΅¬μ—μ„œ μ‚¬μš©λœλ‹€.

NaN은 λ°μ΄ν„°μ…‹μ—μ„œ 값이 μ‘΄μž¬ν•˜μ§€ μ•Šκ±°λ‚˜ μˆ˜ν•™μ μœΌλ‘œ μ •μ˜ν•  수 μ—†λŠ” μƒνƒœλ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 이것은 λ°μ΄ν„°μ˜ λΆ€μž¬, λˆ„λ½, λ˜λŠ” νŠΉμ • μ—°μ‚° κ²°κ³Όκ°€ μ •μ˜λ˜μ§€ μ•ŠλŠ” κ²½μš°μ— ν•΄λ‹Ήν•œλ‹€.

먼제 λ°μ΄ν„°ν”„λ ˆμž„μ„ 톡해 NaN 데이터λ₯Ό μ•Œμ•„λ³΄μž.

>> items2 = [{'bikes': 20, 'pants': 30, 'watches': 35, 'shirts': 15, 'shoes':8, 'suits':45},
   {'watches': 10, 'glasses': 50, 'bikes': 15, 'pants':5, 'shirts': 2, 'shoes':5, 'suits':7},
   {'bikes': 20, 'pants': 30, 'watches': 35, 'glasses': 4, 'shoes':10}]
>> df=pd.DataFrame(data= items2, index= ['store 1','store 2','store 3'])
>> df

κ΅¬κΈ€μ½”λž©μ—μ„œ μ‹€ν–‰

NaNλ₯Ό νŒŒμ•…ν•˜λŠ” 방법

isna() λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ NaN 이 ν•΄λ‹Ήλœ 셀은 true둜 λ‚˜νƒ€λ‚Έλ‹€.

>> #λ³€μˆ˜λͺ….isna
>> df.isna()

거꾸둜 μ•Œκ³  μ‹Άλ‹€λ©΄ notna() λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.
true(값이 μžˆλŠ” κ²ƒ, NaN이 μ•„λ‹Œ κ²ƒ), false(값이 NaN인 κ²ƒ)

>> df.notna()

그리고 μ»¬λŸΌλ³„λ‘œ NaN 의 개수λ₯Ό μ•Œκ³  μ‹Άλ‹€λ©΄ sum() λ©”μ†Œλ“œλ₯Ό μΆ”κ°€ν•˜μ—¬ μ‹€ν–‰ν•œλ‹€.

>> df.isna().sum()
bikes      0
pants      0
watches    0
shirts     1
shoes      0
suits      1
glasses    1
dtype: int64

전체 λ°μ΄ν„°μ—μ„œ NaN 의 개수λ₯Ό μ•Œκ³  μ‹Άλ‹€λ©΄ sum() λ©”μ†Œλ“œλ₯Ό ν•œλ²ˆ 더 μΆ”κ°€ν•œλ‹€.

>> df.isna().sum().sum()
3

 

NaNλ₯Ό μ²˜λ¦¬ν•˜λŠ” 방법

1. NaNλ₯Ό μ‚­μ œν•˜λŠ” 방법

λΉ„μ–΄μžˆλŠ” 데이터λ₯Ό μ°Ύμ•„λ‚΄μ–΄ κ·Έ 행을 μ‚­μ œν•œλ‹€.(보톡 열을 μ‚­μ œν•œλ‹€κΈ° 보단 행을 μ‚­μ œ ν•˜κΈ° λ•Œλ¬Έμ—)

>> df.dropna()

2. νŠΉμ • κ°’μœΌλ‘œ μ±„μš°λŠ” 방법

NaN 데이터가 ν¬ν•¨λœ 행을 μ‚­μ œν•  수 μ—†λ‹€λ©΄ μ±„μš°λŠ” 방법을 μ‚¬μš©ν•΄μ•Όν•œλ‹€.

NaNλ₯Ό 숫자λ₯Ό 0으둜 μ±„μš°κΈ°

fillna() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ NaN  데이터λ₯Ό 0으둜 μ±„μ›Œ NaNλ₯Ό 없앨 수 μžˆλ‹€.

>> df.fillna(0)

 

NaNλ₯Ό 문자 '데이터 μ—†μŒ'으둜 μ±„μš°κΈ°

0 λŒ€μ‹  λ¬Έμžμ—΄ 데이터λ₯Ό λ„£μ–΄μ„œ μ›ν•˜λŠ” λ¬Έμžμ—΄λ‘œ λŒ€μ²΄ν•  수 μžˆλ‹€.

>> df.fillna('데이터 μ—†μŒ')

 

νŠΉμ • NaN λ°μ΄ν„°λ§Œ λ³€κ²½ν•˜κΈ°

λ§Œμ•½ shirts 컬럼의  NaN만 λ³€κ²½ν•˜κ³  μ‹Άλ‹€λ©΄
shirts 컬럼만 μ§€μ •ν•˜μ—¬ NaN 데이터λ₯Ό λ³€κ²½ν•  수 μžˆλ‹€.

>> df['shirts'].fillna('No data')
store 1       15.0
store 2        2.0
store 3    No data
Name: shirts, dtype: object

 

μ•žμ΄λ‚˜ λ’€μ˜ 데이터λ₯Ό μ΄μš©ν•˜μ—¬ μ±„μš°κΈ°

μ•žμ˜ 행을 λ°μ΄ν„°λ‘œ μ±„μš°λŠ” 방법은 fillna λ©”μ†Œλ“œμ˜ ffill속성을 μ‚¬μš©ν•˜κ³  (μ•žμ— fλŠ” forward)
λ’€μ˜ 행을 λ°μ΄ν„°λ‘œ μ±„μš°λŠ” 방법은 bfill속성을 μ‚¬μš©ν•œλ‹€. (bλŠ” back)

axis 속성은 값에 따라 ν–‰μ—΄ λ°©ν–₯을 μ§€μ •ν•  수 μžˆλ‹€.
axis=0: μ—΄ λ°©ν–₯으둜 μž‘λ™
axis=1: ν–‰ λ°©ν–₯으둜 μž‘λ™

>> df.fillna(method= 'ffill', axis=0)

 

각 μ»¬λŸΌλ³„ 평균값, μ΅œμ†Œκ°’, μ΅œλŒ€κ°’μœΌλ‘œ μ±„μš°κΈ°

mean() λ©”μ†Œλ“œλŠ” νŒλ‹€μŠ€μ—μ„œ Seriesλ‚˜ DataFrame의 ν‰κ· μ„ κ³„μ‚°ν•˜λŠ” λ° μ‚¬μš©λœλ‹€. μ΄ λ©”μ†Œλ“œλŠ” μ£Όμ–΄μ§„ μΆ•을 λ”°λΌ ν‰κ· μ„ κ³„μ‚°ν•œλ‹€.

>> df.mean()
bikes      18.333333
pants      21.666667
watches    26.666667
shirts      8.500000
shoes       7.666667
suits      26.000000
glasses    27.000000
dtype: float64
>> df.fillna(df.mean()) # 평균 κ΅¬ν•œλ‹€μŒμ— Nan κ°’ μžλ™μœΌλ‘œ 듀어감

>> df.fillna(df.max()) #μ΅œλŒ€κ°’μœΌλ‘œ μ±„μš°κΈ°

>> df.fillna(df.min()) #μ΅œμ†Œκ°’μœΌλ‘œ μ±„μš°κΈ°

λ°˜μ‘ν˜•