Source code for aitoolbox.utils.dict_util
import collections
import copy
import numpy as np
import torch
from aitoolbox.utils.util import flatten_list_of_lists
[docs]def combine_prediction_metadata_batches(metadata_list):
"""Combines a list of dicts with the same keys and [lists or torch.Tensors or np.arrays] as values into
a single dict with concatenated [lists or torch.Tensors or np.arrays] for each corresponding key
Args:
metadata_list (list): list of dicts with matching keys and [lists or torch.Tensors or np.arrays] for values
Returns:
dict: combined single dict
"""
combined_metadata = {}
for metadata_batch in metadata_list:
for meta_el in metadata_batch:
if meta_el not in combined_metadata:
combined_metadata[meta_el] = []
combined_metadata[meta_el].append(metadata_batch[meta_el])
for meta_el in combined_metadata:
metadata_elements_list = combined_metadata[meta_el]
if isinstance(metadata_elements_list[0], list):
combined_metadata[meta_el] = flatten_list_of_lists(metadata_elements_list)
elif isinstance(metadata_elements_list[0], torch.Tensor):
combined_metadata[meta_el] = torch.cat(metadata_elements_list, dim=0)
elif isinstance(metadata_elements_list[0], np.ndarray):
combined_metadata[meta_el] = np.concatenate(metadata_elements_list, axis=0)
else:
raise TypeError(f'Provided metadata element data type which is not supported '
f'by the function (type: {type(metadata_elements_list[0])}). '
f'Function supports the following data types: list, torch.Tensor and np.array')
return combined_metadata
[docs]def flatten_dict(nested_dict, parent_key='', sep='_'):
"""Flatten the nested dict of dicts of ...
Args:
nested_dict (dict): input dict
parent_key (str):
sep (str): separator when flattening the category
Returns:
dict: flattened dict
"""
items = []
for k, v in nested_dict.items():
new_key = parent_key + sep + k if parent_key else k
if isinstance(v, collections.MutableMapping):
items.extend(flatten_dict(v, new_key, sep=sep).items())
else:
items.append((new_key, v))
return dict(items)
[docs]def combine_dict_elements(list_of_dicts):
"""Combine into single list the elements with the same key across several dicts
Args:
list_of_dicts (list): list of dicts with matching keys
Returns:
dict: combined single dict
"""
combined_dict = {}
for d in list_of_dicts:
for k, v in d.items():
if k not in combined_dict:
combined_dict[k] = []
combined_dict[k].append(v)
return combined_dict
[docs]def flatten_combine_dict(train_history):
"""Flatten all dict of dicts and combine elements with the same key into a single list in the dict
Args:
train_history (dict):
Returns:
dict:
"""
train_history_cp = copy.deepcopy(train_history)
train_history_flat_comb = {}
for k in train_history_cp:
if all(type(el) == dict for el in train_history_cp[k]):
flat_dict_list = [flatten_dict(d) for d in train_history_cp[k]]
combined_dict = combine_dict_elements(flat_dict_list)
for k_comb, v_comb in combined_dict.items():
train_history_flat_comb[f'{k}_{k_comb}'] = v_comb
else:
train_history_flat_comb[k] = train_history_cp[k]
return train_history_flat_comb