누락값 처리¶
In [1]:
from numpy import NaN, NAN, nan
In [2]:
print(NaN ==True)
False
In [3]:
print(NaN == True)
False
In [4]:
# 값 자체가 없으므로 자신과 비교해도 false
print((NaN ==NaN))
False
- 누락값을 확인하는 메서드 isnull, notnull
In [5]:
import pandas as pd
print(pd.isnull(NaN))
True
In [6]:
print(pd.isnull(nan))
True
In [7]:
print(pd.isnull(NAN))
True
In [8]:
print(pd.notnull(NaN))
False
In [9]:
print(pd.notnull(42))
True
In [11]:
print(pd.notnull('missing'))
True
In [18]:
visited = pd.read_csv('../../data/survey_visited.csv')
survey = pd.read_csv('../../data/survey_survey.csv')
visited
Out[18]:
ident | site | dated | |
---|---|---|---|
0 | 619 | DR-1 | 1927-02-08 |
1 | 622 | DR-1 | 1927-02-10 |
2 | 734 | DR-3 | 1939-01-07 |
3 | 735 | DR-3 | 1930-01-12 |
4 | 751 | DR-3 | 1930-02-26 |
5 | 752 | DR-3 | NaN |
6 | 837 | MSK-4 | 1932-01-14 |
7 | 844 | DR-1 | 1932-03-22 |
In [14]:
survey
Out[14]:
taken | person | quant | reading | |
---|---|---|---|---|
0 | 619 | dyer | rad | 9.82 |
1 | 619 | dyer | sal | 0.13 |
2 | 622 | dyer | rad | 7.80 |
3 | 622 | dyer | sal | 0.09 |
4 | 734 | pb | rad | 8.41 |
5 | 734 | lake | sal | 0.05 |
6 | 734 | pb | temp | -21.50 |
7 | 735 | pb | rad | 7.22 |
8 | 735 | NaN | sal | 0.06 |
9 | 735 | NaN | temp | -26.00 |
10 | 751 | pb | rad | 4.35 |
11 | 751 | pb | temp | -18.50 |
12 | 751 | lake | sal | 0.10 |
13 | 752 | lake | rad | 2.19 |
14 | 752 | lake | sal | 0.09 |
15 | 752 | lake | temp | -16.00 |
16 | 752 | roe | sal | 41.60 |
17 | 837 | lake | rad | 1.46 |
18 | 837 | lake | sal | 0.21 |
19 | 837 | roe | sal | 22.50 |
20 | 844 | roe | rad | 11.25 |
In [17]:
vs = visited.merge(survey, left_on='ident', right_on='taken')
vs
Out[17]:
ident | site | dated | taken | person | quant | reading | |
---|---|---|---|---|---|---|---|
0 | 619 | DR-1 | 1927-02-08 | 619 | dyer | rad | 9.82 |
1 | 619 | DR-1 | 1927-02-08 | 619 | dyer | sal | 0.13 |
2 | 622 | DR-1 | 1927-02-10 | 622 | dyer | rad | 7.80 |
3 | 622 | DR-1 | 1927-02-10 | 622 | dyer | sal | 0.09 |
4 | 734 | DR-3 | 1939-01-07 | 734 | pb | rad | 8.41 |
5 | 734 | DR-3 | 1939-01-07 | 734 | lake | sal | 0.05 |
6 | 734 | DR-3 | 1939-01-07 | 734 | pb | temp | -21.50 |
7 | 735 | DR-3 | 1930-01-12 | 735 | pb | rad | 7.22 |
8 | 735 | DR-3 | 1930-01-12 | 735 | NaN | sal | 0.06 |
9 | 735 | DR-3 | 1930-01-12 | 735 | NaN | temp | -26.00 |
10 | 751 | DR-3 | 1930-02-26 | 751 | pb | rad | 4.35 |
11 | 751 | DR-3 | 1930-02-26 | 751 | pb | temp | -18.50 |
12 | 751 | DR-3 | 1930-02-26 | 751 | lake | sal | 0.10 |
13 | 752 | DR-3 | NaN | 752 | lake | rad | 2.19 |
14 | 752 | DR-3 | NaN | 752 | lake | sal | 0.09 |
15 | 752 | DR-3 | NaN | 752 | lake | temp | -16.00 |
16 | 752 | DR-3 | NaN | 752 | roe | sal | 41.60 |
17 | 837 | MSK-4 | 1932-01-14 | 837 | lake | rad | 1.46 |
18 | 837 | MSK-4 | 1932-01-14 | 837 | lake | sal | 0.21 |
19 | 837 | MSK-4 | 1932-01-14 | 837 | roe | sal | 22.50 |
20 | 844 | DR-1 | 1932-03-22 | 844 | roe | rad | 11.25 |
데이터를 입력할 때 누락값이 생기는 경우¶
In [19]:
num_legs = pd.Series({'goat':4, 'amoeba':nan})
print(num_legs)
print(type(num_legs))
goat 4.0
amoeba NaN
dtype: float64
<class 'pandas.core.series.Series'>
In [21]:
scientists = pd.DataFrame({
'Name': ['Rosaline Fanklin', "Willam Gosset"],
'Occupataion': ['Chemist', "Statistician"],
'Born': ['1920-07-25', "1876-06-13"],
'Died': ['1920-04-16', "1937-10-16"],
'missing': [NaN, nan],
})
print(scientists)
print(type(scientists))
Name Occupataion Born Died missing
0 Rosaline Fanklin Chemist 1920-07-25 1920-04-16 NaN
1 Willam Gosset Statistician 1876-06-13 1937-10-16 NaN
<class 'pandas.core.frame.DataFrame'>
범위를 지정하여 데이터를 추출할 때 누락값이 생기는 경우¶
In [26]:
gapminder = pd.read_csv('../../data/gapminder.tsv', sep='\t')
gapminder
Out[26]:
country | continent | year | lifeExp | pop | gdpPercap | |
---|---|---|---|---|---|---|
0 | Afghanistan | Asia | 1952 | 28.801 | 8425333 | 779.445314 |
1 | Afghanistan | Asia | 1957 | 30.332 | 9240934 | 820.853030 |
2 | Afghanistan | Asia | 1962 | 31.997 | 10267083 | 853.100710 |
3 | Afghanistan | Asia | 1967 | 34.020 | 11537966 | 836.197138 |
4 | Afghanistan | Asia | 1972 | 36.088 | 13079460 | 739.981106 |
... | ... | ... | ... | ... | ... | ... |
1699 | Zimbabwe | Africa | 1987 | 62.351 | 9216418 | 706.157306 |
1700 | Zimbabwe | Africa | 1992 | 60.377 | 10704340 | 693.420786 |
1701 | Zimbabwe | Africa | 1997 | 46.809 | 11404948 | 792.449960 |
1702 | Zimbabwe | Africa | 2002 | 39.989 | 11926563 | 672.038623 |
1703 | Zimbabwe | Africa | 2007 | 43.487 | 12311143 | 469.709298 |
1704 rows × 6 columns
In [23]:
life_exp = gapminder.groupby(['year'])['lifeExp'].mean()
print(life_exp)
year
1952 49.057620
1957 51.507401
1962 53.609249
1967 55.678290
1972 57.647386
1977 59.570157
1982 61.533197
1987 63.212613
1992 64.160338
1997 65.014676
2002 65.694923
2007 67.007423
Name: lifeExp, dtype: float64
In [28]:
y2000 = life_exp[life_exp.index > 2000]
print(y2000)
year
2002 65.694923
2007 67.007423
Name: lifeExp, dtype: float64
누락값의 개수 구하기¶
In [29]:
ebola = pd.read_csv('../../data/country_timeseries.csv')
ebola.head()
Out[29]:
Date | Day | Cases_Guinea | Cases_Liberia | Cases_SierraLeone | Cases_Nigeria | Cases_Senegal | Cases_UnitedStates | Cases_Spain | Cases_Mali | Deaths_Guinea | Deaths_Liberia | Deaths_SierraLeone | Deaths_Nigeria | Deaths_Senegal | Deaths_UnitedStates | Deaths_Spain | Deaths_Mali | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1/5/2015 | 289 | 2776.0 | NaN | 10030.0 | NaN | NaN | NaN | NaN | NaN | 1786.0 | NaN | 2977.0 | NaN | NaN | NaN | NaN | NaN |
1 | 1/4/2015 | 288 | 2775.0 | NaN | 9780.0 | NaN | NaN | NaN | NaN | NaN | 1781.0 | NaN | 2943.0 | NaN | NaN | NaN | NaN | NaN |
2 | 1/3/2015 | 287 | 2769.0 | 8166.0 | 9722.0 | NaN | NaN | NaN | NaN | NaN | 1767.0 | 3496.0 | 2915.0 | NaN | NaN | NaN | NaN | NaN |
3 | 1/2/2015 | 286 | NaN | 8157.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 3496.0 | NaN | NaN | NaN | NaN | NaN | NaN |
4 | 12/31/2014 | 284 | 2730.0 | 8115.0 | 9633.0 | NaN | NaN | NaN | NaN | NaN | 1739.0 | 3471.0 | 2827.0 | NaN | NaN | NaN | NaN | NaN |
In [30]:
# count 메서드로 누락값이 아닌 값의 개수를 구함
print(ebola.count())
Date 122
Day 122
Cases_Guinea 93
Cases_Liberia 83
Cases_SierraLeone 87
Cases_Nigeria 38
Cases_Senegal 25
Cases_UnitedStates 18
Cases_Spain 16
Cases_Mali 12
Deaths_Guinea 92
Deaths_Liberia 81
Deaths_SierraLeone 87
Deaths_Nigeria 38
Deaths_Senegal 22
Deaths_UnitedStates 18
Deaths_Spain 16
Deaths_Mali 12
dtype: int64
In [32]:
ebola.shape
Out[32]:
(122, 18)
In [31]:
# shape[0]에서 누락값이 아닌 값의 개수를 빼면 누락값의 개수를 구할 수 있음
num_rows = ebola.shape[0]
num_missing = num_rows - ebola.count()
print(num_missing)
Date 0
Day 0
Cases_Guinea 29
Cases_Liberia 39
Cases_SierraLeone 35
Cases_Nigeria 84
Cases_Senegal 97
Cases_UnitedStates 104
Cases_Spain 106
Cases_Mali 110
Deaths_Guinea 30
Deaths_Liberia 41
Deaths_SierraLeone 35
Deaths_Nigeria 84
Deaths_Senegal 100
Deaths_UnitedStates 104
Deaths_Spain 106
Deaths_Mali 110
dtype: int64
In [34]:
ebola.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 122 entries, 0 to 121
Data columns (total 18 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Date 122 non-null object
1 Day 122 non-null int64
2 Cases_Guinea 93 non-null float64
3 Cases_Liberia 83 non-null float64
4 Cases_SierraLeone 87 non-null float64
5 Cases_Nigeria 38 non-null float64
6 Cases_Senegal 25 non-null float64
7 Cases_UnitedStates 18 non-null float64
8 Cases_Spain 16 non-null float64
9 Cases_Mali 12 non-null float64
10 Deaths_Guinea 92 non-null float64
11 Deaths_Liberia 81 non-null float64
12 Deaths_SierraLeone 87 non-null float64
13 Deaths_Nigeria 38 non-null float64
14 Deaths_Senegal 22 non-null float64
15 Deaths_UnitedStates 18 non-null float64
16 Deaths_Spain 16 non-null float64
17 Deaths_Mali 12 non-null float64
dtypes: float64(16), int64(1), object(1)
memory usage: 17.3+ KB
In [36]:
import numpy as np
In [38]:
# count_nonzero 메서드는 0인 아닌 값의 개수를 세는 메서드
# count_nonzero, isnull 메서드를 조합해서 누락값의 개수를 구함
# 29 + 39 + ... + 106 + 110 = 1214
print(np.count_nonzero(ebola.isnull()))
1214
In [40]:
print(np.count_nonzero(ebola['Cases_Guinea'].isnull()))
29
In [41]:
ebola['Cases_Guinea'].isnull()
Out[41]:
0 False
1 False
2 False
3 True
4 False
...
117 False
118 False
119 False
120 False
121 False
Name: Cases_Guinea, Length: 122, dtype: bool
In [42]:
# value_counts 메서드는 지정한 열의 빈도를 구하는 메서드
print(ebola.Cases_Guinea.value_counts(dropna=False).head())
NaN 29
86.0 3
495.0 2
112.0 2
390.0 2
Name: Cases_Guinea, dtype: int64
In [53]:
print(ebola.Cases_Guinea.value_counts(dropna=True).head())
86.0 3
495.0 2
112.0 2
390.0 2
408.0 1
Name: Cases_Guinea, dtype: int64
In [55]:
# ebola.Cases_Guinea.value_counts
In [54]:
# ebola['Cases_Guinea'].value_counts
누락값 처리하기¶
누락값 변경하기¶
In [57]:
# fillna 메서드에 0을 대입하면 누락값을 0으로 변경
# df의 크기가 매우 크고 메모리를 효율적으로 사용해야 하는 경우 자주 사용하는 메서드
print(ebola.fillna(0).iloc[0:10, 0:5])
Date Day Cases_Guinea Cases_Liberia Cases_SierraLeone
0 1/5/2015 289 2776.0 0.0 10030.0
1 1/4/2015 288 2775.0 0.0 9780.0
2 1/3/2015 287 2769.0 8166.0 9722.0
3 1/2/2015 286 0.0 8157.0 0.0
4 12/31/2014 284 2730.0 8115.0 9633.0
5 12/28/2014 281 2706.0 8018.0 9446.0
6 12/27/2014 280 2695.0 0.0 9409.0
7 12/24/2014 277 2630.0 7977.0 9203.0
8 12/21/2014 273 2597.0 0.0 9004.0
9 12/20/2014 272 2571.0 7862.0 8939.0
In [59]:
# ffill: 누락값이 나타나기 전의 값으로 누락값이 변경
print(ebola.fillna(method='ffill').iloc[0:10, 0:5])
Date Day Cases_Guinea Cases_Liberia Cases_SierraLeone
0 1/5/2015 289 2776.0 NaN 10030.0
1 1/4/2015 288 2775.0 NaN 9780.0
2 1/3/2015 287 2769.0 8166.0 9722.0
3 1/2/2015 286 2769.0 8157.0 9722.0
4 12/31/2014 284 2730.0 8115.0 9633.0
5 12/28/2014 281 2706.0 8018.0 9446.0
6 12/27/2014 280 2695.0 8018.0 9409.0
7 12/24/2014 277 2630.0 7977.0 9203.0
8 12/21/2014 273 2597.0 7977.0 9004.0
9 12/20/2014 272 2571.0 7862.0 8939.0
In [60]:
# 누락값이 나타난 이후의 첫 번째 값으로 앞쪽의 누락값이 모두 변경
# 마지막 값이 누락값인 경우는 처리하지 못한다는 단점이 있음
print(ebola.fillna(method='bfill').iloc[0:10, 0:5])
Date Day Cases_Guinea Cases_Liberia Cases_SierraLeone
0 1/5/2015 289 2776.0 8166.0 10030.0
1 1/4/2015 288 2775.0 8166.0 9780.0
2 1/3/2015 287 2769.0 8166.0 9722.0
3 1/2/2015 286 2730.0 8157.0 9633.0
4 12/31/2014 284 2730.0 8115.0 9633.0
5 12/28/2014 281 2706.0 8018.0 9446.0
6 12/27/2014 280 2695.0 7977.0 9409.0
7 12/24/2014 277 2630.0 7977.0 9203.0
8 12/21/2014 273 2597.0 7862.0 9004.0
9 12/20/2014 272 2571.0 7862.0 8939.0
In [64]:
# interpolate 메서드는 누락값 양쪽에 있는 값을 이용해서 중간값으로 채움
print((8018.0 + 7977.0)/2)
print(ebola.interpolate().iloc[0:10, 0:5])
7997.5
Date Day Cases_Guinea Cases_Liberia Cases_SierraLeone
0 1/5/2015 289 2776.0 NaN 10030.0
1 1/4/2015 288 2775.0 NaN 9780.0
2 1/3/2015 287 2769.0 8166.0 9722.0
3 1/2/2015 286 2749.5 8157.0 9677.5
4 12/31/2014 284 2730.0 8115.0 9633.0
5 12/28/2014 281 2706.0 8018.0 9446.0
6 12/27/2014 280 2695.0 7997.5 9409.0
7 12/24/2014 277 2630.0 7977.0 9203.0
8 12/21/2014 273 2597.0 7919.5 9004.0
9 12/20/2014 272 2571.0 7862.0 8939.0
누락값 삭제하기¶
In [66]:
print(ebola.shape)
(122, 18)
In [67]:
# dropna 메서드: 누락값을 삭제 ,누락값이 포함된 행들이 모두 삭제
# 많은 데이터가 삭제됨
ebola_dropna = ebola.dropna()
print(ebola_dropna.shape)
(1, 18)
In [74]:
print(ebola_dropna)
<bound method DataFrame.dropna of Date Day Cases_Guinea Cases_Liberia Cases_SierraLeone \
0 1/5/2015 289 2776.0 NaN 10030.0
1 1/4/2015 288 2775.0 NaN 9780.0
2 1/3/2015 287 2769.0 8166.0 9722.0
3 1/2/2015 286 NaN 8157.0 NaN
4 12/31/2014 284 2730.0 8115.0 9633.0
.. ... ... ... ... ...
117 3/27/2014 5 103.0 8.0 6.0
118 3/26/2014 4 86.0 NaN NaN
119 3/25/2014 3 86.0 NaN NaN
120 3/24/2014 2 86.0 NaN NaN
121 3/22/2014 0 49.0 NaN NaN
Cases_Nigeria Cases_Senegal Cases_UnitedStates Cases_Spain \
0 NaN NaN NaN NaN
1 NaN NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 NaN NaN NaN NaN
.. ... ... ... ...
117 NaN NaN NaN NaN
118 NaN NaN NaN NaN
119 NaN NaN NaN NaN
120 NaN NaN NaN NaN
121 NaN NaN NaN NaN
Cases_Mali Deaths_Guinea Deaths_Liberia Deaths_SierraLeone \
0 NaN 1786.0 NaN 2977.0
1 NaN 1781.0 NaN 2943.0
2 NaN 1767.0 3496.0 2915.0
3 NaN NaN 3496.0 NaN
4 NaN 1739.0 3471.0 2827.0
.. ... ... ... ...
117 NaN 66.0 6.0 5.0
118 NaN 62.0 NaN NaN
119 NaN 60.0 NaN NaN
120 NaN 59.0 NaN NaN
121 NaN 29.0 NaN NaN
Deaths_Nigeria Deaths_Senegal Deaths_UnitedStates Deaths_Spain \
0 NaN NaN NaN NaN
1 NaN NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 NaN NaN NaN NaN
.. ... ... ... ...
117 NaN NaN NaN NaN
118 NaN NaN NaN NaN
119 NaN NaN NaN NaN
120 NaN NaN NaN NaN
121 NaN NaN NaN NaN
Deaths_Mali
0 NaN
1 NaN
2 NaN
3 NaN
4 NaN
.. ...
117 NaN
118 NaN
119 NaN
120 NaN
121 NaN
[122 rows x 18 columns]>
누락값이 포함된 데이터 계산하기¶
In [75]:
ebola['Cases_multiple'] = ebola['Cases_Guinea'] + ebola['Cases_Liberia'] + \
ebola['Cases_SierraLeone']
In [77]:
# 누락값이 하나라도 있는 행은 계산 결과(Cases_multiple)가 NaN이 됨
ebola_subset = ebola.loc[:, ['Cases_Guinea', 'Cases_Liberia', \
'Cases_SierraLeone', 'Cases_multiple']]
print(ebola_subset.head(n=10))
Cases_Guinea Cases_Liberia Cases_SierraLeone Cases_multiple
0 2776.0 NaN 10030.0 NaN
1 2775.0 NaN 9780.0 NaN
2 2769.0 8166.0 9722.0 20657.0
3 NaN 8157.0 NaN NaN
4 2730.0 8115.0 9633.0 20478.0
5 2706.0 8018.0 9446.0 20170.0
6 2695.0 NaN 9409.0 NaN
7 2630.0 7977.0 9203.0 19810.0
8 2597.0 NaN 9004.0 NaN
9 2571.0 7862.0 8939.0 19372.0
In [88]:
# sum 메서드를 그냥 사용하면 누락값을 포함해서 계산
# 누락값을 무시한 채 계산하려면 skipna 인자값을 True로 설정
print(ebola.Cases_Guinea.sum(skipna=True))
84729.0
In [89]:
print(ebola.Cases_Guinea.sum(skipna=False))
nan
반응형
'데이터분석' 카테고리의 다른 글
[23.06.16] Python pivot_table - 11(2) (0) | 2023.06.16 |
---|---|
[23.06.16] Python melt - 11(1) (0) | 2023.06.16 |
[23.06.15] Python merge - 10(2) (0) | 2023.06.15 |
[23.06.15] Python concat - 10(1) (0) | 2023.06.15 |
[23.06.14] Python Seaborn - 09(2) (0) | 2023.06.14 |