5. Handling Missing Data(결측치 다루기)
In [1]:
from IPython.core.display import display, HTML
display(HTML("<style> .container{width:90% !important;}</style>"))

Handling Missing Data

In [2]:
import pandas as pd
import numpy as np
In [3]:
# 임의의 데이터프레임 생성
df = pd.DataFrame( [ [np.nan, 2, np.nan, 0], 
                     [3, 4, np.nan, 1],
                     [np.nan, np.nan, np.nan, 5] ],
                                 columns = list('ABCD') )
df
Out[3]:
A B C D
0 NaN 2.0 NaN 0
1 3.0 4.0 NaN 1
2 NaN NaN NaN 5

dropna(axis = ?, how = ?, inplace = ?) : 결측치 버리기

  • axis = 0 (default) : 행 버리기 ⟷ axis = 1 : 컬럼 버리기
  • how = 'any' (default) : 행 또는 열의 NaN이 하나라도 있을 때 버리기 ⟷ how = 'all' : 전체 행 또는 열의 값이 NaN일 때 버리기
  • inplace = False (default) : drop한 결과 조회만 하기 ⟷ inplace = True : drop한 결과 데이터프레임에 바로 저장
In [4]:
# 전부다 Null인 컬럼 drop
df.dropna(axis=1, how= 'all') 
Out[4]:
A B D
0 NaN 2.0 0
1 3.0 4.0 1
2 NaN NaN 5
In [5]:
# 하나라도 Null이 있는 컬럼 drop
df.dropna(axis=1, how= 'any') 
Out[5]:
D
0 0
1 1
2 5
In [6]:
# 전부다 Null인 열 drop
df.dropna(axis=0, how='all')
Out[6]:
A B C D
0 NaN 2.0 NaN 0
1 3.0 4.0 NaN 1
2 NaN NaN NaN 5
In [7]:
# 하나라도 Null이 있는 열 drop
df.dropna(axis=0, how='any')
Out[7]:
A B C D


df.fillna : NaN 을 지정해준 값으로 채워줌

In [8]:
# 결측치 0으로 채우기
df.fillna(0)
Out[8]:
A B C D
0 0.0 2.0 0.0 0
1 3.0 4.0 0.0 1
2 0.0 0.0 0.0 5
In [9]:
# 딕셔너리를 사용해서 컬럼별로 지정값으로 채우기
values = { 'A' : 0, 'B': 1, 'C': 2, 'D': 3}
df.fillna(value=values)
Out[9]:
A B C D
0 0.0 2.0 2.0 0
1 3.0 4.0 2.0 1
2 0.0 1.0 2.0 5
In [10]:
# 결측치를 중앙값으로 채우기
fill_na_value = df['D'].median()
df.fillna(fill_na_value)
Out[10]:
A B C D
0 1.0 2.0 1.0 0
1 3.0 4.0 1.0 1
2 1.0 1.0 1.0 5
In [11]:
# 컬럼별로 결측치 데이터 갯수 확인
df.isnull().sum() 
Out[11]:
A    2
B    1
C    3
D    0
dtype: int64
In [12]:
# 컬럼별로 결측치가 아닌 데이터 갯수 확인
df.notnull().sum()
Out[12]:
A    1
B    2
C    0
D    3
dtype: int64
4. Summarize Data(자료 요약하기)
In [1]:
from IPython.core.display import display, HTML
display(HTML("<style> .container{width:90% !important;}</style>"))

Summarize Data

In [2]:
import pandas as pd
import seaborn as sns
import numpy as np
In [3]:
# 예제 데이터셋 불러오기
df = sns.load_dataset('iris')
df.shape
Out[3]:
(150, 5)
In [4]:
df.head()
Out[4]:
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
In [5]:
# 카테고리형 변수가 각 값별로 데이터가 얼마나 있는지 확인
df['species'].value_counts() 
Out[5]:
virginica     50
setosa        50
versicolor    50
Name: species, dtype: int64
In [6]:
# value_counts() 한 것을 데이터 프레임으로 넣기
df['species'].value_counts().to_frame()
# pd.DataFrame(df['species'].value_counts()) 도 같은 결과
Out[6]:
species
virginica 50
setosa 50
versicolor 50
In [7]:
# 데이터 프레임의 행수 확인
len(df)
# df.shape[0] 도 같은 결과
Out[7]:
150
In [8]:
# 변수의 유니크한 값 개수
df['species'].nunique() 
Out[8]:
3
In [9]:
# describe()를 사용해서 기본 통계값들을 확인할 수 있다.
df.describe()
Out[9]:
sepal_length sepal_width petal_length petal_width
count 150.000000 150.000000 150.000000 150.000000
mean 5.843333 3.057333 3.758000 1.199333
std 0.828066 0.435866 1.765298 0.762238
min 4.300000 2.000000 1.000000 0.100000
25% 5.100000 2.800000 1.600000 0.300000
50% 5.800000 3.000000 4.350000 1.300000
75% 6.400000 3.300000 5.100000 1.800000
max 7.900000 4.400000 6.900000 2.500000
In [10]:
# include = 'all' 인자를 넣어주면 categorical 변수에 대한 값인 unique, top, freq도 조회할 수 있음
df.describe(include='all')
Out[10]:
sepal_length sepal_width petal_length petal_width species
count 150.000000 150.000000 150.000000 150.000000 150
unique NaN NaN NaN NaN 3
top NaN NaN NaN NaN virginica
freq NaN NaN NaN NaN 50
mean 5.843333 3.057333 3.758000 1.199333 NaN
std 0.828066 0.435866 1.765298 0.762238 NaN
min 4.300000 2.000000 1.000000 0.100000 NaN
25% 5.100000 2.800000 1.600000 0.300000 NaN
50% 5.800000 3.000000 4.350000 1.300000 NaN
75% 6.400000 3.300000 5.100000 1.800000 NaN
max 7.900000 4.400000 6.900000 2.500000 NaN
In [11]:
# 문자형(카테고리형) 변수에 대한 통계값을 조회할 수 있음
df.describe(include=[np.object])
Out[11]:
species
count 150
unique 3
top virginica
freq 50
In [12]:
# 수치형 변수에 대한 통계값을 조회할 수 있음
df.describe(include=[np.number])
Out[12]:
sepal_length sepal_width petal_length petal_width
count 150.000000 150.000000 150.000000 150.000000
mean 5.843333 3.057333 3.758000 1.199333
std 0.828066 0.435866 1.765298 0.762238
min 4.300000 2.000000 1.000000 0.100000
25% 5.100000 2.800000 1.600000 0.300000
50% 5.800000 3.000000 4.350000 1.300000
75% 6.400000 3.300000 5.100000 1.800000
max 7.900000 4.400000 6.900000 2.500000
In [13]:
# 해당 컬럼의 값 합계
df['petal_width'].sum()
Out[13]:
179.90000000000003
In [14]:
# 해당 컬럼의 null이 아닌 행의 수
df['petal_width'].count()
Out[14]:
150
In [15]:
# 해당 컬럼의 중위수
df['petal_width'].median()
Out[15]:
1.3
In [16]:
# 해당 컬럼의 평균값
df['petal_width'].mean()
Out[16]:
1.199333333333334
In [17]:
# 데이터 프레임 각 컬럼의 평균값
df.mean()
Out[17]:
sepal_length    5.843333
sepal_width     3.057333
petal_length    3.758000
petal_width     1.199333
dtype: float64
In [18]:
# 4분위수 확인하기
df.quantile([0.25, 0.75])
Out[18]:
sepal_length sepal_width petal_length petal_width
0.25 5.1 2.8 1.6 0.3
0.75 6.4 3.3 5.1 1.8
In [19]:
# 데이터 프레임 각 컬럼의 최댓값
df.max()
Out[19]:
sepal_length          7.9
sepal_width           4.4
petal_length          6.9
petal_width           2.5
species         virginica
dtype: object
In [20]:
# 데이터 프레임 각 컬럼의 최솟값
df.min()
Out[20]:
sepal_length       4.3
sepal_width          2
petal_length         1
petal_width        0.1
species         setosa
dtype: object
In [21]:
# 데이터 프레임 각 컬럼의 분산
df.var()
Out[21]:
sepal_length    0.685694
sepal_width     0.189979
petal_length    3.116278
petal_width     0.581006
dtype: float64
In [22]:
# 데이터 프레임의 각 컬럼의 표준편차
df.std()
Out[22]:
sepal_length    0.828066
sepal_width     0.435866
petal_length    1.765298
petal_width     0.762238
dtype: float64

apply(function)

In [23]:
# 임의의 함수 설정
def smp(x):
    # 뒤에서 세번째까지의 문자를 가져오는 함수
    x = x[-3:]
    return x 
In [24]:
# lambda 익명함수 적용
df['species_3'] = df['species'].apply(lambda x : x[:3]) 
In [25]:
# 설정해둔 함수 적용
df['species_4'] = df['species'].apply(smp) 
In [26]:
df.head()
Out[26]:
sepal_length sepal_width petal_length petal_width species species_3 species_4
0 5.1 3.5 1.4 0.2 setosa set osa
1 4.9 3.0 1.4 0.2 setosa set osa
2 4.7 3.2 1.3 0.2 setosa set osa
3 4.6 3.1 1.5 0.2 setosa set osa
4 5.0 3.6 1.4 0.2 setosa set osa
3. Subset Observations(Columns) (열 데이터 다루기)
In [1]:
from IPython.core.display import display, HTML
display(HTML("<style> .container{width:90% !important;}</style>"))
In [2]:
import pandas as pd
import seaborn as sns
In [3]:
# 예시 데이터 불러오기
df = sns.load_dataset('iris')
print(df.shape)
df.head()
(150, 5)
Out[3]:
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa

데이터프레임에서 특정 컬럼 정보만 불러오기

In [4]:
columns = ['sepal_length', 'sepal_width', 'species']
df[columns].head()
Out[4]:
sepal_length sepal_width species
0 5.1 3.5 setosa
1 4.9 3.0 setosa
2 4.7 3.2 setosa
3 4.6 3.1 setosa
4 5.0 3.6 setosa
In [5]:
# 이 방식에서는 한글이나 특수문자가 들어간 컬럼명을 쓸 수 없음
df.sepal_width.head() 
Out[5]:
0    3.5
1    3.0
2    3.2
3    3.1
4    3.6
Name: sepal_width, dtype: float64
In [6]:
df['sepal_width'].head()
Out[6]:
0    3.5
1    3.0
2    3.2
3    3.1
4    3.6
Name: sepal_width, dtype: float64

정규 표현식으로 특정컬럼 불러오기

df.filter( regex = 'regex' )

  • '\.' : 점( . )을 포함하고 있는 문자열
In [7]:
df.filter(regex='\,').head(3)
Out[7]:
0
1
2
  • 'length$' : 특정문자열(length)로 끝나는 문자열
In [8]:
df.filter(regex='length$').head(3)
Out[8]:
sepal_length petal_length
0 5.1 1.4
1 4.9 1.4
2 4.7 1.3
  • '_' : _ 를 포함하고 있는 문자열
In [9]:
df.filter(regex='_').head(3)
Out[9]:
sepal_length sepal_width petal_length petal_width
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
  • '^sepal' : 특정문자열(Sepal)로 시작하는 문자열
In [10]:
df.filter(regex='^sepal').head(3)
Out[10]:
sepal_length sepal_width
0 5.1 3.5
1 4.9 3.0
2 4.7 3.2
  • *'^(?!species$).' : 특정문자열('species')이 없는 문자열
In [11]:
df.filter(regex='^(?!species).*').head(3)
Out[11]:
sepal_length sepal_width petal_length petal_width
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
  • '^x[1-5]$' : 특정문자(x)로 시작하고 특정문자(1, 2, 3, 4, 5)로 끝나는 문자열
In [12]:
df.filter(regex='^x[1-5]$').head(3)
Out[12]:
0
1
2

df.loc[ ]와 df.iloc[ ] 비교

In [13]:
df.loc[2:5, 'sepal_width':'petal_width']
Out[13]:
sepal_width petal_length petal_width
2 3.2 1.3 0.2
3 3.1 1.5 0.2
4 3.6 1.4 0.2
5 3.9 1.7 0.4

loc와는 다르게 iloc로 검색을 했을 때 a:b 면 b-1행까지 검색을 함
iloc는 인덱스번호만 입력이 가능함

In [14]:
df.iloc[2:5:,  1:3]
Out[14]:
sepal_width petal_length
2 3.2 1.3
3 3.1 1.5
4 3.6 1.4

loc 를 통해 logic 조건으로 행을 지정하고, 컬럼명을 선택할 수 있음

In [15]:
df.loc[df['sepal_length']>3 , ['sepal_length','sepal_width']].head()
Out[15]:
sepal_length sepal_width
0 5.1 3.5
1 4.9 3.0
2 4.7 3.2
3 4.6 3.1
4 5.0 3.6

+ Recent posts