Hello,
I’ve got an ArviZ and PyMC combo question. I’ve been working with some uneven, long, data that I’m managing with multi-indexes. This workflow works pretty well except PyMC models can’t accept multi-indexes in the the coords
dictionary. To go around this, I just create a 1D array like this coords = {'tests': np.arange(num_tests)
. After the model inference is done, I can assign the 1D array to a multi-index like this: idata = idata.assign_coords(multi_index_tests).unstack()
. This is where things get difficult. Say my multi-index is named “tests”, after unstacking, I will have xarray dims
named tests_level_0, tests_level_1, etc...
.
In theory, I could then use rename
to name these dims
to what they’re supposed to represent. However, I’ve found that this can quickly become difficult if there are name clashes. For example, in my model, I have two different multi-indexes that share some, but not all, levels. This means I end up with something like trying to rename both designs_level_1
and tests_level_1
to time
, which xarray doesn’t allow. Another complication is when one level of the multi-index is already a coord
in the PyMC model so renaming the unstacked multi-index is a clear name clash.
I ultimately get around these through an awkward combination of reset_index
, assign_coords
, and rename
(see below) but this wasn’t well documented in either ArviZ or xarray, but I wanted know if there is a better way to do this? Is there a way I could pass the multi-index to PyMC and have it handle this?
Thank you all for your time.
For clarity, this is ultimately what I ended up doing:
times = [0, 15, 30, 45, 60, 75, 90, 120]
replications = [0, 1, 2]
groups = [
"posterior_predictive",
"posterior",
"constant_data",
"prior",
"prior_predictive",
"observed_data",
]
ds = idata.assign_coords(
mindex_coords_tests,
groups=groups,
).unstack()
ds = ds.assign_coords(mindex_coords_designs, groups=groups).unstack()
ds = (
ds.reset_index(
["designs_level_0", "tests_level_0", "designs_level_1", "tests_level_1"],
groups=groups,
drop=True,
)
.assign_coords({"times": times})
.rename(
{
"designs_level_0": "voids",
"tests_level_0": "voids",
"tests_level_1": "times",
"designs_level_1": "times",
"tests_level_2": "replications",
},
groups=groups,
)
)