|
| 1 | +module NetworkDynamicsDataFramesExt |
| 2 | + |
| 3 | +using NetworkDynamics: NetworkDynamics, Network |
| 4 | +using DataFrames: DataFrames, DataFrame |
| 5 | +using OrderedCollections: OrderedDict |
| 6 | + |
| 7 | +function _df_from_list(list, f) |
| 8 | + df = DataFrame() |
| 9 | + for (i, v) in list |
| 10 | + row = OrderedDict{Symbol,Any}() |
| 11 | + row[:idx] = i |
| 12 | + for sym in f(v) |
| 13 | + if NetworkDynamics.has_default_or_init(v, sym) |
| 14 | + row[sym] = NetworkDynamics.get_default_or_init(v, sym) |
| 15 | + else |
| 16 | + row[sym] = missing |
| 17 | + end |
| 18 | + end |
| 19 | + push!(df, NamedTuple(row); cols=:union) |
| 20 | + end |
| 21 | + df |
| 22 | +end |
| 23 | +function _df_from_pair(list, pair) |
| 24 | + key, f = pair |
| 25 | + df = DataFrame() |
| 26 | + for (i, v) in list |
| 27 | + row = OrderedDict{Symbol,Any}(:idx => i, key => f(v)) |
| 28 | + push!(df, NamedTuple(row); cols=:union) |
| 29 | + end |
| 30 | + df |
| 31 | +end |
| 32 | + |
| 33 | +function NetworkDynamics.describe_vertices(nw::Network, extras...; parameters=true, states=true, batch=nothing) |
| 34 | + pairs = enumerate(nw.im.vertexm); |
| 35 | + batches = map(idx -> findfirst(batch -> idx ∈ batch.indices, nw.vertexbatches), first.(pairs)) |
| 36 | + |
| 37 | + if !isnothing(batch) |
| 38 | + idxs = findall(b -> b ∈ batch, batches) |
| 39 | + pairs = collect(pairs)[idxs] |
| 40 | + batch = collect(batches)[idxs] |
| 41 | + end |
| 42 | + isempty(pairs) && return DataFrame() |
| 43 | + |
| 44 | + basedf = DataFrame( |
| 45 | + idx = first.(pairs), |
| 46 | + name = map(v->last(v).name, pairs), |
| 47 | + batch = map(idx -> findfirst(batch -> idx ∈ batch.indices, nw.vertexbatches), first.(pairs)), |
| 48 | + ) |
| 49 | + |
| 50 | + dfs = [basedf,] |
| 51 | + if parameters |
| 52 | + push!(dfs, _df_from_list(pairs, NetworkDynamics.psym)) |
| 53 | + end |
| 54 | + if states |
| 55 | + push!(dfs, _df_from_list(pairs, NetworkDynamics.sym)) |
| 56 | + end |
| 57 | + for p in extras |
| 58 | + push!(dfs, _df_from_pair(pairs, p)) |
| 59 | + end |
| 60 | + |
| 61 | + foldl((a,b) -> DataFrames.leftjoin(a,b; on=:idx), dfs) |
| 62 | +end |
| 63 | + |
| 64 | +function NetworkDynamics.describe_edges(nw::Network, extras...; parameters=true, states=true, batch=nothing) |
| 65 | + pairs = enumerate(nw.im.edgem); |
| 66 | + batches = map(idx -> findfirst(batch -> idx ∈ batch.indices, nw.layer.edgebatches), first.(pairs)) |
| 67 | + |
| 68 | + if !isnothing(batch) |
| 69 | + idxs = findall(b -> b ∈ batch, batches) |
| 70 | + pairs = collect(pairs)[idxs] |
| 71 | + batch = collect(batches)[idxs] |
| 72 | + end |
| 73 | + isempty(pairs) && return DataFrame() |
| 74 | + |
| 75 | + basedf = DataFrame( |
| 76 | + idx = first.(pairs), |
| 77 | + srcdst = map(idx -> nw.im.edgevec[idx].src => nw.im.edgevec[idx].dst, first.(pairs)), |
| 78 | + name = map(v->last(v).name, pairs), |
| 79 | + batch = map(idx -> findfirst(batch -> idx ∈ batch.indices, nw.vertexbatches), first.(pairs)), |
| 80 | + ) |
| 81 | + |
| 82 | + dfs = [basedf,] |
| 83 | + if parameters |
| 84 | + push!(dfs, _df_from_list(pairs, NetworkDynamics.psym)) |
| 85 | + end |
| 86 | + if states |
| 87 | + push!(dfs, _df_from_list(pairs, NetworkDynamics.sym)) |
| 88 | + end |
| 89 | + for p in extras |
| 90 | + push!(dfs, _df_from_pair(pairs, p)) |
| 91 | + end |
| 92 | + |
| 93 | + foldl((a,b) -> DataFrames.leftjoin(a,b; on=:idx), dfs) |
| 94 | +end |
| 95 | + |
| 96 | +end |
0 commit comments