딥스탯 2018. 10. 9. 16:32
03_missingvalues(한글)

Introduction to DataFrames

Bogumił Kamiński, 2018년 5월 23일

출처

함께보기

In [1]:
using DataFrames # 패키지 불러오기

결측치(missing values) 다루기

Missings.Missing 타입(tyoe)은 결측치(missingv alue)를 다룰 수 있게 해준다.

In [2]:
missing, typeof(missing)
Out[2]:
(missing, Missing)

배열(Array)는 적절한 union type을 자동적으로 만든다.

In [3]:
x = [1, 2, missing, 3]
Out[3]:
4-element Array{Union{Missing, Int64},1}:
 1       
 2       
  missing
 3       

ismissing을 이용하면 결측인지 아닌지 확인할 수 있다.

In [4]:
ismissing(1), ismissing(missing), ismissing(x), ismissing.(x)
Out[4]:
(false, true, false, Bool[false, false, true, false])

Missings.T(eltype())을 이용하면 Union에서 Missing 타입과 결합된 타입을 추출할 수 있다.

In [5]:
eltype(x), Missings.T(eltype(x))
Out[5]:
(Union{Missing, Int64}, Int64)

missing과 대소비교한 결과는 missing이다.

In [6]:
missing == missing, missing != missing, missing < missing
Out[6]:
(missing, missing, missing)

다른 타입과의 비교도 마찬가지로 missing이다.

In [7]:
1 == missing, 1 != missing, 1 < missing
Out[7]:
(missing, missing, missing)

isequal, isless, === 이 세 가지를 사용하면 논리(Bool) 타입을 반환한다.

In [8]:
isequal(missing, missing), missing === missing, isequal(1, missing), isless(1, missing)
Out[8]:
(true, true, false, true)

결측치는 어떤 수치값보다 크다 (무한대보다도 더!).

In [9]:
isless(Inf,missing)
Out[9]:
true

다음 몇 가지 예는, 많은 함수들이 missing을 다루고 있음을 알 수 있다.

In [10]:
map(x -> x(missing), [sin, cos, zero, sqrt]) # part 1
Out[10]:
4-element Array{Missing,1}:
 missing
 missing
 missing
 missing
In [11]:
map(x -> x(missing, 1), [+, - , *, /, div]) # part 2
Out[11]:
5-element Array{Missing,1}:
 missing
 missing
 missing
 missing
 missing
In [12]:
using Statistics
map(x -> x([1,2,missing]), [minimum, maximum, extrema, mean, float]) # part 3
Out[12]:
5-element Array{Any,1}:
 missing                                   
 missing                                   
 (missing, missing)                        
 missing                                   
 Union{Missing, Float64}[1.0, 2.0, missing]

skipmissing은 결측치를 없앤 결과를 반환한다. collectskipmissing을 이용해서 결측치가 없는 배열을 만들 수 있다.

In [13]:
skipmissing([1, missing, 2, missing])
Out[13]:
Base.SkipMissing{Array{Union{Missing, Int64},1}}(Union{Missing, Int64}[1, missing, 2, missing])
In [14]:
collect(skipmissing([1, missing, 2, missing]))
Out[14]:
2-element Array{Int64,1}:
 1
 2

마찬가지로, collectMissing.replace를 이용해서 결측치를 특정 값으로 바꾼 배열을 얻을 수 있다. (이 경우에는 NaN으로 바꿨다.)

In [15]:
collect(Missings.replace([1.0, missing, 2.0, missing], NaN))
Out[15]:
4-element Array{Float64,1}:
   1.0
 NaN  
   2.0
 NaN  

같은 작업을 coalesce로 할 수 있다.

In [16]:
coalesce.([1.0, missing, 2.0, missing], NaN)
Out[16]:
4-element Array{Float64,1}:
   1.0
 NaN  
   2.0
 NaN  

recode를 이용해도 같은 작업을 할 수 있다.

In [17]:
recode([1.0, missing, 2.0, missing], missing=>NaN)
Out[17]:
4-element Array{Float64,1}:
   1.0
 NaN  
   2.0
 NaN  

unique를 이용하면 missing이 있는 유일값을, levels를 이용하면 missing이 없는 유일값을 얻을 수 있다.

In [18]:
unique([1, missing, 2, missing]), levels([1, missing, 2, missing])
Out[18]:
(Union{Missing, Int64}[1, missing, 2], [1, 2])

allowmissing을 이용해서 x에 missing을 허용하도록 하고,

In [19]:
x = [1,2,3]
y = allowmissing(x)
Out[19]:
3-element Array{Union{Missing, Int64},1}:
 1
 2
 3

disallowmissing을 이용해서 다시 missing을 허용하지 않도록 한다.

In [20]:
z = disallowmissing(y)
x,y,z
Out[20]:
([1, 2, 3], Union{Missing, Int64}[1, 2, 3], [1, 2, 3])

이 다음 예제에서는 x의 각 열의 타입이 처음에는 Int64임을 보여준다. allowmissing!를 사용하여 1행과 3행에서 결측치를 허용한 후에, 행 타입은 Int64Missings.MissingUnion이 된다.

In [21]:
x = DataFrame(Int, 2, 3)
println("Before: ", eltypes(x))
allowmissing!(x, 1) # 1행이 missing을 허용하도록
allowmissing!(x, :x3) # :x3 행이 missing을 허용하도록
println("After: ", eltypes(x))
Before: Type[Int64, Int64, Int64]
After: Type[Union{Missing, Int64}, Int64, Union{Missing, Int64}]

다음 예제에서는 completecases를 써서 데이터프레임의 열 데이터가 완전한지 알 수 있게 해준다.

In [22]:
x = DataFrame(A=[1, missing, 3, 4], B=["A", "B", missing, "C"])
println(x)
println("Complete cases:\n", completecases(x))
4×2 DataFrame
│ Row │ A       │ B       │
│     │ Int64⍰String⍰ │
├─────┼─────────┼─────────┤
│ 1   │ 1       │ A       │
│ 2   │ missing │ B       │
│ 3   │ 3       │ missing │
│ 4   │ 4       │ C       │
Complete cases:
Bool[true, false, false, true]

dropmissing이나 dropmissing!을 써서 missing이 있는 행은 모두 다 지울 수 있다.

In [23]:
y = dropmissing(x)
dropmissing!(x)
[x, y]
Out[23]:
2-element Array{DataFrame,1}:
 2×2 DataFrame
│ Row │ A      │ B       │
│     │ Int64⍰String⍰ │
├─────┼────────┼─────────┤
│ 1   │ 1      │ A       │
│ 2   │ 4      │ C       │
 2×2 DataFrame
│ Row │ A      │ B       │
│     │ Int64⍰String⍰ │
├─────┼────────┼─────────┤
│ 1   │ 1      │ A       │
│ 2   │ 4      │ C       │

eltypes를 통해서 데이터프레임을 보면 missing 을 허용하는지 아닌지는 알 수 있다.

In [24]:
eltypes(x)
Out[24]:
2-element Array{Type,1}:
 Union{Missing, Int64} 
 Union{Missing, String}

결측치를 없앴으므로, disallowmissing!을 써서 더 이상 결측치를 허용하지 않도록 하자.

In [25]:
disallowmissing!(x)
eltypes(x)
Out[25]:
2-element Array{Type,1}:
 Int64 
 String