딥스탯 2018. 10. 15. 10:58
09_reshaping(한글)

Introduction to DataFrames

Bogumił Kamiński, Apr 21, 2018

출처

함께보기

In [1]:
using DataFrames # load package

데이터프레임 모양 바꾸기 (Reshaping DataFrames)

넓은 형태에서 긴 형태로 (Wide to long)

In [2]:
x = DataFrame(id=[1,2,3,4], id2=[1,1,2,2], M1=[11,12,13,14], M2=[111,112,113,114])
Out[2]:
idid2M1M2
Int64Int64Int64Int64
11111111
22112112
33213113
44214114
In [3]:
melt(x, :id, [:M1, :M2]) # id 변수를 먼저 넣고, measure 변수를 넣는다. meltdf는 뷰(view)를 만든다.
Out[3]:
variablevalueid
SymbolInt64Int64
1M1111
2M1122
3M1133
4M1144
5M21111
6M21122
7M21133
8M21144
In [4]:
# 추가적으로 행 이름을 지정해 줄 수 있다. (melt와 stack은 같은 역할을 하지만 인자(argument)의 순서가 다르다.
stack(x, [:M1, :M2], :id, variable_name=:key, value_name=:observed) # measure가 먼저오고 id가 나중에 온다. stackdf는 뷰(view)를 만든다.
Out[4]:
keyobservedid
SymbolInt64Int64
1M1111
2M1122
3M1133
4M1144
5M21111
6M21122
7M21133
8M21144
In [5]:
# 만일 melt나 stack 함수에 두 번째 인자가 없다면, 모든 다른 행이 두 번째 인자인 것 처럼 실행된다.
# 하지만 measure 변수는 <: AbstractFloat 타입일 때만 선택된다.
melt(x, [:id, :id2])
Out[5]:
variablevalueidid2
SymbolInt64Int64Int64
1M11111
2M11221
3M11332
4M11442
5M211111
6M211221
7M211332
8M211442
In [6]:
melt(x, [1, 2]) # 행 이름 대신에 인덱스(index)를 사용할 수도 있다.
Out[6]:
variablevalueidid2
SymbolInt64Int64Int64
1M11111
2M11221
3M11332
4M11442
5M211111
6M211221
7M211332
8M211442
In [7]:
bigx = DataFrame(rand(10^6, 10)) # 데이터프레임을 만드는 것과 뷰(view)를 만드는 것의 차이를 보기 위해 만듦.
bigx[:id] = 1:10^6
@time melt(bigx, :id)
@time melt(bigx, :id)
@time meltdf(bigx, :id)
@time meltdf(bigx, :id);
  0.253764 seconds (172.28 k allocations: 237.679 MiB, 33.81% gc time)
  0.201528 seconds (144 allocations: 228.889 MiB, 53.45% gc time)
  0.387475 seconds (633.47 k allocations: 32.617 MiB, 15.52% gc time)
  0.000169 seconds (117 allocations: 6.453 KiB)
In [8]:
x = DataFrame(id = [1,1,1], id2=['a','b','c'], a1 = rand(3), a2 = rand(3))
Out[8]:
idid2a1a2
Int64CharFloat64Float64
11'a'0.3270330.248548
21'b'0.3478820.853054
31'c'0.8625270.489913
In [9]:
melt(x)
Out[9]:
variablevalueidid2
SymbolFloat64Int64Char
1a10.3270331'a'
2a10.3478821'b'
3a10.8625271'c'
4a20.2485481'a'
5a20.8530541'b'
6a20.4899131'c'
In [10]:
melt(DataFrame(rand(3,2))) # 기본적으로 stack과 melt는 float타입을 value행으로 취급한다.
Out[10]:
variablevalue
SymbolFloat64
1x10.509455
2x10.873081
3x10.820428
4x20.27679
5x20.422507
6x20.535333
In [11]:
df = DataFrame(rand(3,2))
df[:key] = [1,1,1]
mdf = melt(df) # key가 중복되더라도 아무런 메세지 없이 실행된다.
Out[11]:
variablevaluekey
SymbolFloat64Int64
1x10.3620251
2x10.613071
3x10.4755871
4x20.7781
5x20.7716351
6x20.03121331

긴 형태에서 넓은 형태로 (Long to wide)

In [12]:
x = DataFrame(id = [1,1,1], id2=['a','b','c'], a1 = rand(3), a2 = rand(3))
Out[12]:
idid2a1a2
Int64CharFloat64Float64
11'a'0.6757090.172469
21'b'0.06526960.748051
31'c'0.3944190.452423
In [13]:
y = melt(x, [1,2])
display(x)
display(y)
idid2a1a2
Int64CharFloat64Float64
11'a'0.6757090.172469
21'b'0.06526960.748051
31'c'0.3944190.452423
variablevalueidid2
SymbolFloat64Int64Char
1a10.6757091'a'
2a10.06526961'b'
3a10.3944191'c'
4a20.1724691'a'
5a20.7480511'b'
6a20.4524231'c'
In [14]:
unstack(y, :id2, :variable, :value) # key가 하나인 기본적인 unstack
Out[14]:
id2a1a2
CharFloat64⍰Float64⍰
1'a'0.6757090.172469
2'b'0.06526960.748051
3'c'0.3944190.452423
In [15]:
unstack(y, :variable, :value) # 모든 행이 key로 받아들여진다.
Out[15]:
idid2a1a2
Int64CharFloat64⍰Float64⍰
11'a'0.6757090.172469
21'b'0.06526960.748051
31'c'0.3944190.452423
In [16]:
# 기본적으로 (:id, :variable, :value)가 가정돼있다. 이 경우에는 중복되는 key가 있어서 경고(Warning)을 출력한다.
unstack(y)
┌ Warning: In the future `unstack(df)` will call `unstack(df, :variable, :value)`. use `unstack(df, :id, :variable, :value)` to treat `:id` as the only `rowkeys` column
│   caller = top-level scope at In[16]:1
└ @ Core In[16]:1
┌ Warning: Duplicate entries in unstack at row 2 for key 1 and variable a1.
└ @ DataFrames /home/yt/.julia/packages/DataFrames/1PqZ3/src/abstractdataframe/reshape.jl:244
Out[16]:
ida1a2
Int64Float64⍰Float64⍰
110.3944190.452423
In [17]:
df = stack(DataFrame(rand(3,2)))
Out[17]:
variablevalue
SymbolFloat64
1x10.971137
2x10.0227282
3x10.0354664
4x20.42655
5x20.287566
6x20.278549
In [18]:
unstack(df, :variable, :value) # key 행이 없으면 unstack이 되지 않는다.
ArgumentError: No key column found

Stacktrace:
 [1] unstack(::DataFrame, ::Array{Symbol,1}, ::Int64, ::Int64) at /home/yt/.julia/packages/DataFrames/1PqZ3/src/abstractdataframe/reshape.jl:279
 [2] unstack(::DataFrame, ::Int64, ::Int64) at /home/yt/.julia/packages/DataFrames/1PqZ3/src/abstractdataframe/reshape.jl:269
 [3] unstack(::DataFrame, ::Symbol, ::Symbol) at /home/yt/.julia/packages/DataFrames/1PqZ3/src/abstractdataframe/reshape.jl:265
 [4] top-level scope at In[18]:1