【问题标题】:How to create a incidence matrix in Julia Dataframes如何在 Julia Dataframes 中创建关联矩阵
【发布时间】:2021-11-20 15:43:11
【问题描述】:
继续我的学习,我正在努力寻找一种方法来创建关联矩阵。
我找到了“解决方案”how-can-i-create-an-incidence-matrix-in-julia,但我既不完全理解也不完全可以使用该解决方案
如果我们有一些简单的数据框,比如
df = DataFrame(Lines = (1:20), From = rand(1:10,20), To = rand(1:10,20))
现在我想将该 Dataframe 转换为仅由“0”、“1”(起点)和“-1”(终点)组成的关联矩阵。它应该看起来像这样(除了它们在矩阵中应该是 1 和 -1...但我不知道该怎么做...)
感谢您的帮助!
标签:
dataframe
matrix
jupyter-notebook
julia
ijulia-notebook
【解决方案1】:
你可以这样做:
julia> using DataFrames
julia> df = DataFrame(Lines = (1:20), From = rand(1:10,20), To = rand(1:10,20))
20×3 DataFrame
Row │ Lines From To
│ Int64 Int64 Int64
─────┼─────────────────────
1 │ 1 4 9
2 │ 2 3 8
3 │ 3 9 1
4 │ 4 3 9
5 │ 5 4 1
6 │ 6 9 8
7 │ 7 3 4
8 │ 8 8 2
9 │ 9 3 7
10 │ 10 6 5
11 │ 11 7 9
12 │ 12 8 9
13 │ 13 8 6
14 │ 14 9 3
15 │ 15 3 6
16 │ 16 5 10
17 │ 17 3 1
18 │ 18 8 5
19 │ 19 2 9
20 │ 20 5 6
julia> let imat = zeros(Int, nrow(df), max(maximum(df.From), maximum(df.To))) # assuming nodes start being numbered from 1
for (i, (from, to)) in enumerate(zip(df.From, df.To))
imat[i, from] = 1
imat[i, to] = -1
end
res = DataFrame(imat, Symbol.(axes(imat, 2)))
insertcols!(res, 1, :Lines => df.Lines)
end
20×11 DataFrame
Row │ Lines 1 2 3 4 5 6 7 8 9 10
│ Int64 Int64 Int64 Int64 Int64 Int64 Int64 Int64 Int64 Int64 Int64
─────┼─────────────────────────────────────────────────────────────────────────────
1 │ 1 0 0 0 1 0 0 0 0 -1 0
2 │ 2 0 0 1 0 0 0 0 -1 0 0
3 │ 3 -1 0 0 0 0 0 0 0 1 0
4 │ 4 0 0 1 0 0 0 0 0 -1 0
5 │ 5 -1 0 0 1 0 0 0 0 0 0
6 │ 6 0 0 0 0 0 0 0 -1 1 0
7 │ 7 0 0 1 -1 0 0 0 0 0 0
8 │ 8 0 -1 0 0 0 0 0 1 0 0
9 │ 9 0 0 1 0 0 0 -1 0 0 0
10 │ 10 0 0 0 0 -1 1 0 0 0 0
11 │ 11 0 0 0 0 0 0 1 0 -1 0
12 │ 12 0 0 0 0 0 0 0 1 -1 0
13 │ 13 0 0 0 0 0 -1 0 1 0 0
14 │ 14 0 0 -1 0 0 0 0 0 1 0
15 │ 15 0 0 1 0 0 -1 0 0 0 0
16 │ 16 0 0 0 0 1 0 0 0 0 -1
17 │ 17 -1 0 1 0 0 0 0 0 0 0
18 │ 18 0 0 0 0 -1 0 0 1 0 0
19 │ 19 0 1 0 0 0 0 0 0 -1 0
20 │ 20 0 0 0 0 1 -1 0 0 0 0
在解决方案中我使用了let,以确保操作快速。
【解决方案2】:
另一种可能的方式是使用广播:
inci=zeros(Int,20,10)
setindex!.(Ref(inci), 1, df.Lines, df.From)
setindex!.(Ref(inci), -1, df.Lines, df.To)
这会产生一个Matrix,当然可以在需要时将其转换为 DataFrame:
julia> inci
20×10 Matrix{Int64}:
0 -1 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 -1 0 0
0 0 0 0 0 0 0 -1 1 0
0 -1 0 0 0 0 0 1 0 0
0 0 0 -1 0 0 1 0 0 0
0 1 -1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 -1
0 1 -1 0 0 0 0 0 0 0
0 0 1 0 -1 0 0 0 0 0
0 0 0 0 0 0 -1 0 0 0
-1 0 0 0 1 0 0 0 0 0
1 0 0 0 0 0 -1 0 0 0
0 0 0 0 0 0 -1 0 1 0
1 0 0 0 -1 0 0 0 0 0
-1 0 0 0 0 0 0 0 0 1
0 0 0 -1 0 0 0 0 0 1
0 0 0 0 0 -1 0 0 0 1
0 0 0 0 0 1 0 0 0 -1
0 0 0 0 0 0 -1 0 0 0
0 0 -1 0 0 0 0 1 0 0