티스토리 뷰

01_constructors(한글)

패키지 DataFrames을 먼저 부르면서 시작하자.

In [1]:
using DataFrames

생성자(Constructors) 와 변환(conversion)

생성자(Constructors)

이 세션에서, 우리는 DataFrame() 생성자를 이용해서 데이터프레임(DataFrame)을 생성하는 많은 방법을 배울거다.

먼저, 빈(empty) 데이터프레임은 쉽게 만들 수 있다.

In [2]:
DataFrame() # empty DataFrame
Out[2]:

혹은 키워드 인수(keyword arguments)를 이용해서 데이터프레임에 열을 추가할 수 있다.

In [3]:
DataFrame(A=1:3, B=rand(3), C=randstring.([3,3,3])) # 그냥 쓰면 오류난다.
UndefVarError: randstring not defined

Stacktrace:
 [1] top-level scope at In[3]:1
In [4]:
using Random
DataFrame(A=1:3, B=rand(3), C=Random.randstring.([3,3,3]))
Out[4]:
ABC
Int64Float64String
110.2631489dT
220.0721952XYd
330.813375WYR

데이터프레임을 딕셔너리(dictionary)로 부터 만들 수도 있는데, 이 경우 키(key)별로 정렬되어 열 이름으로 들어간다.

In [5]:
x = Dict("A" => [1,2], "B" => [true, false], "C" => ['a', 'b'])
DataFrame(x)
Out[5]:
ABC
Int64BoolChar
11true'a'
22false'b'

위의 예제는 딕셔너리를 먼저 만들어줬지만, 데이터프레임의 인수를 딕셔너리 키-값(key-value) 쌍으로 넣을 수도 있다.

참고로 이 경우, : 기호를 사용해서 열 이름을 선언하며, 키별로 정렬되지 않는다. 예를 들어, A라는 열을 만들고 싶다면 :A로 선언한다.

In [6]:
DataFrame(:A => [1,2], :B => [true, false], :C => ['a', 'b'])
Out[6]:
ABC
Int64BoolChar
11true'a'
22false'b'

아래는 벡터(vector)의 벡터(vector)로부터 데이터프레임을 만든 것인데, 이 때 각각의 벡터가 열이 된다.

In [7]:
DataFrame([rand(3) for i in 1:3])
Out[7]:
x1x2x3
Float64Float64Float64
10.7942290.3772630.0714833
20.4050640.4117120.40019
30.8588750.2740740.674826

벡터의 원소로 이루어진 한 행의 데이터프레임을 만드려면, 아래와 같이 쓰면 될 것 같지만, 작동하지 않고 에러를 뱉어낸다. (예전에는 작동했지만 현재는 폐기되고 작동하지 않는다.)

In [8]:
DataFrame(rand(3))
ArgumentError: unable to construct DataFrame from Array{Float64,1}

Stacktrace:
 [1] DataFrame(::Array{Float64,1}) at /home/yt/.julia/packages/DataFrames/1PqZ3/src/other/tables.jl:32
 [2] top-level scope at In[8]:1

그래서 전치된(transposed) 벡터를 사용해야 한다.(이렇게하면 지원되는 생성자에 2차원 배열을 효과적으로 전달할 수 있다.)

In [9]:
DataFrame(transpose([1, 2, 3]))
Out[9]:
x1x2x3
Int64Int64Int64
1123

두 번재 인수(argument)에 열 이름을 줄 수 있다.

In [10]:
DataFrame([1:3, 4:6, 7:9], [:A, :B, :C])
Out[10]:
ABC
Int64Int64Int64
1147
2258
3369

아래는 행렬(matrix)로부터 데이터프레임을 만들었다.

In [11]:
DataFrame(rand(3,4))
Out[11]:
x1x2x3x4
Float64Float64Float64Float64
10.6291590.5829660.2402790.904271
20.9986430.1100630.7723630.69006
30.2124450.7137420.2297750.221431

그리고 똑같이 두 번째 인수에 이름을 넣을 수 있다.

In [12]:
DataFrame(rand(3,4), Symbol.('a':'d'))
Out[12]:
abcd
Float64Float64Float64Float64
10.5714690.4998210.7988880.892562
20.2645110.6433220.6508720.320339
30.1823280.4560880.292180.499611

또한 초기화되지 않은(uninitialized) 데이터프레임을 생성할 수도 있다.

열 타입(type)과 이름, 열 갯수를 넣은 결과가 아래에 있다. Any >: Missing 이기 대문에 열 :C 에서 missing을 얻었다.

In [13]:
DataFrame([Int, Float64, Any], [:A, :B, :C], 1)
Out[13]:
ABC
Int64Float64Any
11400674769187046.92025e-310missing

아래는 같은 데이터프레임인데, 열 :C가 #undef 이다.

In [14]:
DataFrame([Int, Float64, String], [:A, :B, :C], 1)
Out[14]:
ABC
Int64Float64String
11400631784898566.92019e-310#undef

열 이름은 있지만 행은 없는 데이터프레임을 선언할 수도 있다.

In [15]:
DataFrame([Int, Float64, String], [:A, :B, :C], 0)
Out[15]:
ABC
Int64Float64String

아래는 동질적인(Homogeneous) 데이터프레임을 빠르게 생성하는 구문이다.

In [16]:
DataFrame(Int, 3, 5)
Out[16]:
x1x2x3x4x5
Int64Int64Int64Int64Int64
1140067592119856140067540633344140066203421808140067592176128140067592176128
2140067444304512140067591551056140066210800176140067444301376140067444301376
3140067444304384140067444301376140067447490544140066201352816140066201352832

비슷하지만, 동질적이지 않은(nonhomogeneous) 열인 경우는 아래처럼 하면 된다.

In [17]:
DataFrame([Int, Float64], 4)
Out[17]:
x1x2
Int64Float64
11400674442977366.92026e-310
21400662036030246.92019e-310
31400662013751366.92019e-310
41400631784898566.92019e-310

마지막으로 기존 데이터프레임을 복사하여 데이터프레임을 만들 수 있다.

참고로 copy는 단순한 복사본을 만들 때 사용한다.

In [18]:
y = DataFrame(x)
z = copy(x)
Out[18]:
Dict{String,Array{T,1} where T} with 3 entries:
  "B" => Bool[true, false]
  "A" => [1, 2]
  "C" => ['a', 'b']
In [19]:
x
Out[19]:
Dict{String,Array{T,1} where T} with 3 entries:
  "B" => Bool[true, false]
  "A" => [1, 2]
  "C" => ['a', 'b']
In [20]:
y
Out[20]:
ABC
Int64BoolChar
11true'a'
22false'b'
In [21]:
z
Out[21]:
Dict{String,Array{T,1} where T} with 3 entries:
  "B" => Bool[true, false]
  "A" => [1, 2]
  "C" => ['a', 'b']
In [22]:
(x === y), (x === z), isequal(x, z)
Out[22]:
(false, false, true)

행렬로의 변환(Conversion)

열 2개와 행 2개인 데이터프레임을 생성하면서 시작하자.

In [23]:
x = DataFrame(x=1:2, y=["A", "B"])
Out[23]:
xy
Int64String
11A
22B

Matrix함수를 이용해서 데이터프레임을 행렬로 만들 수 있다.

In [24]:
Matrix(x)
Out[24]:
2×2 Array{Any,2}:
 1  "A"
 2  "B"

만약 데이터프레임missing이 있더라도 먹힌다.

In [25]:
x = DataFrame(x=1:2, y=[missing,"B"])
Out[25]:
xy
Int64String⍰
11missing
22B
In [26]:
Matrix(x)
Out[26]:
2×2 Array{Any,2}:
 1  missing
 2  "B"    

이전의 두 예제에서, Julia는 Any타입을 원소로 가지는 행렬로 변환했다. 이는 우리가 넣는 데이터프레임에 따라서 알아서 유추하는데, 아래의 예를 보면 명확하게 알 수 있다. 정수의 데이터프레임Matrix에 전달하면, 타입이 Int64인 2D 배열(array)을 생성한다.

In [27]:
x = DataFrame(x=1:2, y=3:4)
Out[27]:
xy
Int64Int64
113
224
In [28]:
Matrix(x)
Out[28]:
2×2 Array{Int64,2}:
 1  3
 2  4

다음 예제는 Julia가 Union을 이용해서 올바로 유추하는 것을 볼 수 있다.

In [29]:
x = DataFrame(x=1:2, y=[missing,4])
Out[29]:
xy
Int64Int64⍰
11missing
224
In [30]:
Matrix(x)
Out[30]:
2×2 Array{Union{Missing, Int64},2}:
 1   missing
 2  4       

참고로 missingInt로 강제로 변환할 수 없다!

In [31]:
Matrix{Int}(x)
cannot convert a DataFrame containing missing values to array (found for column y)

Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] convert(::Type{Array{Int64,2}}, ::DataFrame) at /home/yt/.julia/packages/DataFrames/1PqZ3/src/abstractdataframe/abstractdataframe.jl:722
 [3] Array{Int64,2}(::DataFrame) at /home/yt/.julia/packages/DataFrames/1PqZ3/src/abstractdataframe/abstractdataframe.jl:729
 [4] top-level scope at In[31]:1

열 이름 중복

데이터프레임에는 기본적으로 열 이름을 반복적으로 쓸 수 없다. makeunique 키워드 인수를 사용해서 반복되는 이름을 반복되지 않게 자동적으로 바꿀 수 있다.

In [32]:
df = DataFrame(:a=>1, :a=>2, :a_1=>3; makeunique=true)
Out[32]:
aa_2a_1
Int64Int64Int64
1123

그냥 써도 warning이 뜰 뿐, 이름을 자동적으로 바꾼다.

In [33]:
df = DataFrame(:a=>1, :a=>2, :a_1=>3)
┌ Warning: Duplicate variable names are deprecated: pass makeunique=true to add a suffix automatically.
│   caller = ip:0x0
└ @ Core :-1
Out[33]:
aa_2a_1
Int64Int64Int64
1123

열 이름을 인자(argument)로 쓰는 경우에는, makeunique를 써도 자동적으로 반복되지 않게 바꿀 수 없다.

In [34]:
df = DataFrame(a=1, a=2, makeunique=true)
syntax: keyword argument "a" repeated in call to "DataFrame"

'Flux in Julia > Learning Julia (Intro_to_Julia_DFs)' 카테고리의 다른 글

03. missingvalues (한글)  (0) 2018.10.09
03. missingvalues  (0) 2018.10.09
02. basicinfo (한글)  (0) 2018.10.08
02. basicinfo  (0) 2018.10.08
01. Constructors  (0) 2018.10.07
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함