Reputation: 45
I am a Python newbie and am struggling with reorganising data contained in nested dictionaries. The original data are like this:
['period_1': {'metric_1':{'person_1': 0, 'person_2': 1},
{'metric_2': {'person_1': 2, 'person_2': 3}}, 'period_2' :{ ...}
What I want to get to is panel data, with people as the main key, followed by periods, followed by metrics. Like this:
{'person_1': {'period_1': {'metric_1': 0, 'metric_2': 2}, 'period_2':
{'metric_1': 4, 'metric_2': 6}, 'period_2'{ ... }}, 'person_2': { ...}
What I tried so far (the dictionary allUsers
is going to be the place where I store my reorganised data. It already has persons' IDs as keys, and empty dicts as values):
allUsers = {'pippo':{}, 'pluto':{}}
for t in range (len (periods)):
for user in allUsers:
allUsers[user][t] = {}
period = periods[t]
for metric in period:
for person in period[metric]:
allUsers[person][t] = {metric: period[metric][person]}
For some reason, this does not work. It only stores one of the two metrics.
>>> allUsers
{'pippo': {0: {'metric1': 1}, 1: {'metric1': 1}},
'pluto': {0: {'metric1': 2}, 1: {'metric1': 1}}}
Thank you in advance for any help.
Upvotes: 1
Views: 91
Reputation: 388
You're iterating over periods, metrics and persons, so the composite key [person][period] is not going to be unique for each iteration step. When you assign to that key you overwrite whatever was there previously, i.e. the previous metric dictionary.
Upvotes: 0
Reputation: 90899
The issue is that for every new period/metric you find for a person, you are creating a new dictionary and adding to allUsers[person][t]
in the line -
allUsers[person][t] = {metric: period[metric][person]}
Hence it only comes once. You actually want to add a new key/value if t
already exists in allUsers
. Example -
for metric in period:
for person in period[metric]:
allUsers[person][t][metric] = period[metric][person]
But assuming periods
is a dictionary , you can simplify this using dict.setdefault
. Example -
result = {}
for period, value in periods.items():
for metric, v in value.items():
for person,val in v.items():
result.setdefault(person,{}).setdefault(period,{}).set(metric,val)
Upvotes: 1