NamedArrays
是一个很棒的包,可以为行和列命名,并且似乎符合这个问题的要求。假设数据在 data.csv
中,以下是一种解决方法(使用 Pkg.add("NamedArrays")
安装 NamedArrays
):
data,header = readcsv("data.csv",header=true);
cols = unique(vec([(header[j+1],data[i,j+1]) for i in 1:size(data,1),j=1:2]))
rows = data[:,1]
using NamedArrays
narr = NamedArray(zeros(Int,length(rows),length(cols)),(rows,cols),("id","attr"));
for r=1:size(data,1),c=2:size(data,2) narr[data[r,1],(header[c],data[r,c])] = 1 ; end
现在我们有以下内容(注意我为了更好的打印结果已经转置了
narr
):
julia> narr'
10x6 NamedArray{Int64,2}:
attr ╲ id │ A B C D E F
──────────┼─────────────────
("x",22) │ 1 0 0 0 1 0
("x",4) │ 0 1 0 0 0 0
("x",21) │ 0 0 1 0 0 0
("x",26) │ 0 0 0 1 0 0
("x",2) │ 0 0 0 0 0 1
("y",2) │ 1 0 0 1 0 0
("y",21) │ 0 1 0 0 0 0
("y",360) │ 0 0 1 0 0 0
("y",58) │ 0 0 0 0 1 0
("y",347) │ 0 0 0 0 0 1
但是,如果需要使用DataFrames
,类似的技巧也应该适用。
---------- 更新 ----------
如果应该忽略值的列,即x=2和y=2都应在值为2的列上设置1,则代码变为:
using NamedArrays
data,header = readcsv("data.csv",header=true);
rows = data[:,1]
cols = map(string,sort(unique(vec(data[:,2:end]))))
narr = NamedArray(zeros(Int,length(rows),length(cols)),(rows,cols),("id","attr"));
for r=1:size(data,1),c=2:size(data,2) narr[data[r,1],string(data[r,c])] = 1 ; end
提供:
julia> narr
6x8 NamedArray{Int64,2}:
id ╲ attr │ 2 4 21 22 26 58 347 360
──────────┼───────────────────────────────────────
A │ 1 0 0 1 0 0 0 0
B │ 0 1 1 0 0 0 0 0
C │ 0 0 1 0 0 0 0 1
D │ 1 0 0 0 1 0 0 0
E │ 0 0 0 1 0 1 0 0
F │ 1 0 0 0 0 0 1 0
ModelFrame()
和ModelMatrix()
函数?它们可能具有你所需的功能。此外,还有一个sparse()
函数可用于创建稀疏矩阵(这就是你需要创建的)。这个函数虽然能用,但实现起来比较复杂。 - Michael Ohlrogge