Hi all, quick question (hopefully) related to doing an operation on DataFrames.
I am trying to improve the transformation below so any help would be great. More context and MWE are at the bottom.
Thanks for all the help.
df_flows_subsetting_matching_to(rp, a) =
@view df_flows[(df_flows.rp .== rp) .&& (df_flows.to .== a), :]
sum_matching(df, time_block, rp) =
coalesce(sum(df.flow .* length.(Ref(time_block) .∩ df.time_block) * 3.14rp), AffExpr(0.0))
transform!(
df_cons,
[:rp, :asset, :time_block] =>
ByRow((rp, a, T) -> sum_matching(
df_flows_subsetting_matching_to(a, rp, T), T, rp)
) => :incoming_term,
)
The number of elements in the time_block
columns grows to ~8000 in our current cases.
More context:
I am essentially trying to compute
\displaystyle \sum_{T_f} f_{(u,a), rp, T_f} \times |T_f \cap T_a| \times \phi(rp) \qquad \forall a, rp, T_a \in \mathcal{P}_{a, rp}
The set \mathcal{P}_{a, rp} depends on a and rp. Each variation is a line of df_cons
below. Each different value of f is on df_flows
.
This is related to Speeding up JuMP model creation with sets that depend on other indexes - #6 by slwu89
MWE: Including previous code
using DataFrames, JuMP
df_flows = DataFrame(;
from = ["p1", "p1", "p2", "p2", "p1", "p2"],
to = ["d", "d", "d", "d", "d", "d"],
rp = [1, 1, 1, 1, 2, 2],
time_block = [1:3, 4:6, 1:2, 3:6, 1:6, 1:6],
index = 1:6,
)
model = Model()
df_flows.flow = [
@variable(
model,
base_name = "flow[($(row.from),$(row.to)), $(row.rp), $(row.time_block)]"
) for row in eachrow(df_flows)
]
df_cons = DataFrame(;
asset = ["p1", "p1", "p1", "p2", "p2", "d", "d", "d"],
rp = [1, 1, 2, 1, 2, 1, 1, 2],
time_block = [1:3, 4:6, 1:6, 1:6, 1:6, 1:4, 5:6, 1:6],
index = 1:8,
)
df_flows_subsetting_matching_to(rp, a) =
@view df_flows[(df_flows.rp .== rp) .&& (df_flows.to .== a), :]
sum_matching(df, time_block, rp) =
coalesce(sum(df.flow .* length.(Ref(time_block) .∩ df.time_block) * 3.14rp), AffExpr(0.0))
transform!(
df_cons,
[:rp, :asset, :time_block] =>
ByRow((rp, a, T) -> sum_matching(
df_flows_subsetting_matching_to(rp, a), T, rp)
) => :incoming_term,
)