Сделайте матрицу из словаря в Юлии, где ключи - это строки, которые я должен разделить - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть словарь вида

"san-diego.new-york" => 0.225
"seattle.topeka"     => 0.162
"san-diego.chicago"  => 0.162
"seattle.new-york"   => 0.225
"san-diego.topeka"   => 0.126
"seattle.chicago"    => 0.153

Я хочу преобразовать это в матрицу 2x3, где i - это набор san-diego, seattle, а j - это набор new-york, topeka, chicago. Я пытался разделить ключи с помощью split.(keys(dict),"."), но ничего не получилось.

Я хочу сделать это, чтобы потом выполнить вычисления вида M[i][j]=0.5.

edit: я создал новый словарь, в котором ключи являются кортежами. Я не знаю, поможет ли это.

c = Dict("san-diego.new-york" => 0.225, "seattle.topeka" => 0.162, "san-diego.chicago"  => 0.162
, "seattle.new-york"   => 0.225, "san-diego.topeka"   => 0.126, "seattle.chicago"    => 0.153)

a = split.(keys(c),".")
b = collect(values(c))

new_c = Dict((a[i][1],a[i][2])=>b[i] for i in 1:length(b))

В итоге я написал следующую функцию

function fillmatrix()

    c = Dict("san-diego.new-york" => 0.225, "seattle.topeka"     => 0.162, "san-diego.chicago"  => 0.162
    , "seattle.new-york"   => 0.225, "san-diego.topeka"   => 0.126, "seattle.chicago"    => 0.153)

    a = split.(keys(c),".")
    b = collect(values(c))

    new_c = Dict((a[i][1],a[i][2])=>b[i] for i=1:length(b))

    list_i = []
    list_j = []
    for (u,v) in keys(new_c)
        push!(list_i,u)
        push!(list_j,v)
    end

    i = unique(list_i)
    j = unique(list_j)

    A = zeros((length(i),length(j)))


    for ii in i
        for jj in j
            A[findfirst(x->x==ii,i),findfirst(x->x==jj,j)] = new_c[(ii,jj)]
        end
    end

    return A
end

Но это похоже на долгий обходной путь, и я хотел бы обобщить его на несколько измерений. Какие-нибудь мысли? Заранее спасибо.

1 Ответ

0 голосов
/ 14 ноября 2018

Я дам решение из вашего оригинального словаря (другой может быть скорректирован соответственно). Вы можете использовать пакет NamedArrays.jl для решения вашей проблемы. Вот полное решение:

using NamedArrays

d = Dict("san-diego.new-york" => 0.225,
         "seattle.topeka"     => 0.162,
         "san-diego.chicago"  => 0.162,
         "seattle.new-york"   => 0.225,
         "san-diego.topeka"   => 0.126,
         "seattle.chicago"    => 0.153)

s = split.(keys(d), '.')
row = unique(string.(getindex.(s, 1)))
col = unique(string.(getindex.(s, 2)))

m = NamedArray([d[r*"."*c] for r in row, c in col],
               (row, col), ("from", "to"))

(предполагается, что все пары строк-столбцов присутствуют в противном случае вместо d[r*"."*c] запись get(d, r*"."*c, missing) и в записях отсутствуют значения, которых нет в вашем словаре)

А теперь вы можете написать:

julia> m
2×3 Named Array{Float64,2}
from ╲ to │ new-york    topeka   chicago
──────────┼─────────────────────────────
san-diego │    0.225     0.126     0.162
seattle   │    0.225     0.162     0.153

julia> m["san-diego", "new-york"]
0.225

julia> m[2,3]
0.153

(по сути, вы можете использовать имена или целочисленные индексы для ссылки на столбцы / строки)

Также обратите внимание, что я конвертирую row и col записи в String, но мы также можем оставить их как SubString s (т.е. пропустить string. часть в вызове), но String выглядит немного приятнее при печати в виде NamedArray строка / столбец.

...