Flux in Julia/Learning Julia (Intro_to_Julia_DFs)
07. factors (한글)
딥스탯
2018. 10. 13. 17:08
Introduction to DataFrames¶
Bogumił Kamiński, Apr 21, 2018
출처¶
함께보기¶
- https://deepstat.tistory.com/69 (01. constructors)(in English)
- https://deepstat.tistory.com/70 (01. constructors)(한글)
- https://deepstat.tistory.com/71 (02. basicinfo)(in English)
- https://deepstat.tistory.com/72 (02. basicinfo)(한글)
- https://deepstat.tistory.com/73 (03. missingvalues)(in English)
- https://deepstat.tistory.com/74 (03. missingvalues)(한글)
- https://deepstat.tistory.com/75 (04. loadsave)(in English)
- https://deepstat.tistory.com/76 (04. loadsave)(한글)
- https://deepstat.tistory.com/77 (05. columns)(in English)
- https://deepstat.tistory.com/78 (05. columns)(한글)
- https://deepstat.tistory.com/79 (06. rows)(in English)
- https://deepstat.tistory.com/80 (06. rows)(한글)
- https://deepstat.tistory.com/81 (07. factors)(in English)
- https://deepstat.tistory.com/82 (07. factors)(한글)
In [1]:
using DataFrames # load package
범주형 배열로 작업하기 (Working with CategoricalArrays)¶
생성자 (Constructor)¶
In [2]:
x = categorical(["A", "B", "B", "C"]) # 비순서형(unordered) 범주.
Out[2]:
In [3]:
y = categorical(["A", "B", "B", "C"], ordered=true) # 순서형(ordered) 범주. 기본적으로, 순서(order)는 정렬순서(sorting order).
Out[3]:
In [4]:
z = categorical(["A","B","B","C", missing]) # 결측(missing)이 있는 순서형 범주.
Out[4]:
In [5]:
c = cut(1:10, 5) # 순서형. 같은 수로(into equal counts). 레이블(label)의 이름을 바꾸거나 나누는 범위 지정(give custom breaks) 가능.
Out[5]:
In [6]:
by(DataFrame(x=cut(randn(100000), 10)), :x, d -> DataFrame(n=nrow(d)), sort=true) # 단지 제대로 작동하는지 확인하기 위한 코드.
Out[6]:
In [7]:
v = categorical([1,2,2,3,3]) # 글자타입(string)이 아닌 정수타입(integer)를 포함함.
Out[7]:
In [8]:
Vector{Union{String, Missing}}(z) # 다시 원래의 벡터(vector)로 돌리고 싶을 때 사용.
Out[8]:
레벨 관리하기 (Managing levels)¶
In [9]:
arr = [x,y,z,c,v]
Out[9]:
In [10]:
isordered.(arr) # 범주형 배열 (categorical array)이 순서형(ordered)인지 아닌지 확인.
Out[10]:
In [11]:
ordered!(x, true), isordered(x) # x를 강제로 순서형(ordered)으로 만들기
Out[11]:
In [12]:
ordered!(x, false), isordered(x) # 다시 비순서형(unordered)으로 만들기
Out[12]:
In [13]:
levels.(arr) # 레벨(levels) 나열하기
Out[13]:
In [14]:
unique.(arr) # 결측(missing)이 포함돼있음.
Out[14]:
In [15]:
y[1] < y[2] # y가 순서형(ordered) 범주라서 비교할 수 있음.
Out[15]:
In [16]:
v[1] < v[2] # 비록 정수타입(integers)지만, 비순서형(unordered) 범주라서 비교할 수 없음.
In [17]:
levels!(y, ["C", "B", "A"]) # 순서형 범주의 순서를 바꿀 수 있다. 보통 순서형 범주배열(ordered categorical array)에서 유용하다.
Out[17]:
In [18]:
y[1] < y[2] # 순서가 바뀌었음을 알 수 있다.
Out[18]:
In [19]:
levels!(z, ["A", "B"]) # 무조건 모든 레벨을 지정해줘야한다.
In [20]:
levels!(z, ["A", "B"], allow_missing=true) # 아니면 나머지 레벨을 missing으로 간주하도록 만들 수도 있다.
Out[20]:
In [21]:
z[1] = "B"
z # z에 "B"만 있도록 만들었다.
Out[21]:
In [22]:
levels(z) # 그렇지만 레벨에는 여전히 "A"가 남아있다.
Out[22]:
In [23]:
droplevels!(z) # 없는 레벨을 지울 수 있다.
levels(z)
Out[23]:
데이터 다루기 (Data manipulation)¶
In [24]:
x, levels(x)
Out[24]:
In [25]:
x[2] = "0"
x, levels(x) # 마지막에 새로운 레벨이 추가됐다. (비순서형일때만 사용가능하다.)
Out[25]:
In [26]:
v, levels(v)
Out[26]:
In [27]:
v[1] + v[2] # 비록 정수타입(int)이더라도 계산할 수 없다.
In [28]:
Vector{Int}(v) # 데이터 자체를 정수타입(int)으로 변환하거나
Out[28]:
In [29]:
get(v[1]) + get(v[2]) # 혹은 get으로 값 하나만 추출해야한다.
Out[29]:
In [30]:
get.(v) # 이 get.은 결측이 없을 때만 작동할거다.
Out[30]:
In [31]:
get.(z) # 결측이 있으니까 안 된다.
In [32]:
Vector{Union{String, Missing}}(z) # 변환해야만 한다.
Out[32]:
In [33]:
z[1]*z[2], z.^2 # 예외적으로, 글자타입(string)을 기반으로 한 범주배열(categorical array)일 때만 계산가능하다.
Out[33]:
In [34]:
recode([1,2,3,4,5,missing], 1=>10) # 이는 array의 값을 inplace로 바꿨다(recode).
Out[34]:
In [35]:
recode([1,2,3,4,5,missing], "a", 1=>10, 2=>20) # 매핑하지 않은 값에 대해서 일괄적으로 바꿀 수도 있다.
Out[35]:
In [36]:
recode([1,2,3,4,5,missing], 1=>10, missing=>"missing") # 결측치(missing)을 바꾸기 위해서는 정확하게 콕 집어서 써줘야만 한다.
Out[36]:
In [37]:
t = categorical([1:5; missing])
t, levels(t)
Out[37]:
In [38]:
recode!(t, [1,3]=>2)
t, levels(t) # recode를 쓰면 레벨자체가 바뀐다는 것을 알아둬야 한다.
Out[38]:
In [39]:
t = categorical([1,2,3], ordered=true)
levels(recode(t, 2=>0, 1=>-1)) # 만일 새로운 레벨이 추가된다면, 나중에 추가한 순으로 큰 값이 된다.
Out[39]:
In [40]:
t = categorical([1,2,3,4,5], ordered=true) # 만일 매핑하지 않은 값이 있다면, 그 값이 가장 큰 값이 된다.
levels(recode(t, 300, [1,2]=>100, 3=>200))
Out[40]:
비교 (Comparisons)¶
In [41]:
x = categorical([1,2,3])
Out[41]:
In [42]:
xs = [x, categorical(x), categorical(x, ordered=true), categorical(x, ordered=true)]
Out[42]:
In [43]:
levels!(xs[2], [3,2,1])
Out[43]:
In [44]:
levels!(xs[4], [2,3,1])
Out[44]:
In [45]:
[a == b for a in xs, b in xs] # 모든 값이 다 같다. (내용만 비교한다.)
Out[45]:
In [46]:
signature(x::CategoricalArray) = (x, levels(x), isordered(x)) # 이것이 실제로 범주배열(categorical array)의 모든 정보다.
Out[46]:
In [47]:
signature(xs[1])
Out[47]:
In [48]:
signature(xs[2])
Out[48]:
In [49]:
signature(xs[3])
Out[49]:
In [50]:
signature(xs[4])
Out[50]:
In [51]:
# 전부다 다르다. 참고로 x[1]과 x[2]는 비순서형 범주지만, level 순서가 다르다.
[signature(a) == signature(b) for a in xs, b in xs]
Out[51]:
In [52]:
x[1] < x[2] # 비순서형 범주배열의 각 요소들은 비교할 수 없다.
In [53]:
t[1] < t[2] # 하지만 순서형은 비교할 수 있다.
Out[53]:
In [54]:
isless(x[1], x[2]) # isless 함수는 비순서형 범주배열에서도 똑같이 작용한다.
Out[54]:
In [55]:
y = deepcopy(x) # 하지만 아예 다른 범주배열과는 비교할 수 없다.
isless(x[1], y[2])
In [56]:
isless(get(x[1]), get(y[2])) # get을 이용하면 범주배열의 내용을 비교할 수 있다.
Out[56]:
In [57]:
x[1] == y[2] # 같은지 비교하는 것은 다른 범주배열이라도 작동한다.
Out[57]:
데이터프레임 안의 범주형 행 (Categorical columns in a DataFrame)¶
In [58]:
df = DataFrame(x = 1:3, y = 'a':'c', z = ["a","b","c"])
Out[58]:
In [59]:
categorical!(df) # 모든 string타입의 행을 범주형(categorical)으로 바꾼다. (character타입은 해당사항 없다.)
Out[59]:
In [60]:
showcols(df)
Out[60]:
In [61]:
categorical!(df, :x) # :x행을 범주형으로 바꾸라고 강제했다.
Out[61]:
In [62]:
showcols(df)
Out[62]: