Converting Dense Axis array results into dataframe

Hello,

I have the following two-dimensional dense axis array results extracted from a constraint.

Rows represent time stamps [T] and columns represent nodes [N]. Is there a way of converting the DenseAxisArray into a dataframe with the same dimensions?

Thanks

Can you provide an MWE? See some advice on asking a question here

2 Likes

Sure, below is a small example. I have commented out the parts that are not central to the discussion. To elaborate on my earlier query, I am trying to convert the two-dimensional shadow price results obtained from the energy balance constraint (EB_nodal) into a dataframe.

#using JuMP, DataFrames, CSV, GLPK 

generators = DataFrame(index = ["OIL_A", "GAS_B", "NUC_C"], 
                        node = ["zonea", "zoneb", "zonec"],
                        cost = [30,10,5], g_max = [50,60,70], 
                        plant_type = ["conventional","conventional","conventional"])
demand = [0 0 50; 0 0 100; 0 0 150]

T = convert(Array{Int64}, 1:3) #Time
N = convert(Array{Int64}, 1:3) #node
L = convert(Array{Int64}, 1:3) 
C = generators.index

locName = Dict(1 => "zonea", 2 => "zoneb", 3 => "zonec")
incidence = [1 -1 0; 1 0 -1; 0 1 -1]
model = Model(GLPK.Optimizer)

#variables
#@variable(model, vGEN[T, c in C]>=0)
#@variable(model, vFLOW[T, L]) 

#Objective function
#@expression(model, DispCost[t in T], sum(vGEN[t, c]*generators[findfirst(==(c), generators.index), :].cost for c in C)) 
#@objective(model, Min, sum(Dispatch_Model[:DispCost])) 

#Constraints

#@constraint(model, cMaxPower[t in T, c in C], vGEN[t,c] <= generators[findfirst(==(c), C), :].g_max)
#@expression(model, convGEN[t in T, n in N], sum(vGEN[t, c]* (locName[n] == generators[findfirst(==(c), C), :node] ? 1.0 : 0.0) for c in C))

@constraint(model,
 EB_nodal[t in T, n in N],
 demand[t,n] == convGEN[t,n]
  - sum(incidence[l, n]*vFLOW[t, l] for l in L)
) #main constraint
optimize!(model)
nodal_pr = shadow_price.(EB_nodal) * -1 #How do i convert a DenseAxisArray results into a dataframe

Shadow price results from EB_nodal constraint

2-dimensional DenseAxisArray{Float64,2,...} with index sets:
    Dimension 1, [1, 2, 3]
    Dimension 2, [1, 2, 3]
And data, a 3×3 Matrix{Float64}:
  5.0   5.0   5.0
 10.0  10.0  10.0
 30.0  30.0  30.0

Thanks!

There’s no special support. You’d have to construct the dataframe manually. Potentially something like this:

t_list = [t for t in T for _ in N]
n_list = [n for _ in T for n in N]
x_list = [nodal_pr[t, n] for (t, n) in zip(t_list, n_list)]
DataFrame(t = t_list, n = n_list, shadow_price = x_list)
1 Like

This hopefully still works:

You can then do an DataFrames.unstack to pivot the table.

2 Likes

Thanks @jd-foster, this function works

2 Likes

Thanks @odow. This approach works as well. Following @jd-fosters suggestion, i added the unstack dataframe line

t_list = [t for t in T for _ in N]
n_list = [n for _ in T for n in N]
x_list = [nodal_pr[t, n] for (t, n) in zip(t_list, n_list)]
nodal_price = DataFrame(t = t_list, n = n_list, shadow_price = x_list)
new_nodal_price = unstack(nodal_price, :t, :n, :shadow_price)

Thanks!