Reputation: 143
Can anyone guide me in this? I have a dictionary in the following format:
date_wise_data = {
'2018-04-09':{
'user1': 3,
'user2': 1,
'user3': 1,
'user4': 1
},
'2018-04-08': {
'user1': 2,
'user2': 0,
'user3': 1,
'user4': 1
},
'2018-04-07': {
'user1': 6,
'user2': 5,
'user3': 1,
'user4': 2
},
'2018-04-06': {
'user1': 2,
'user2': 0,
'user3': 1,
'user4': 1
},
'2018-04-05': {
'user1': 2,
'user2': 0,
'user3': 2,
'user4': 8
},
'2018-04-04': {
'user1': 0,
'user2': 0,
'user3': 5,
'user4': 1
},
'2018-04-03': {
'user1': 8,
'user2': 0,
'user3': 5,
'user4': 1
}
}
My requirement is to create a dictionary in the following format:
user_data = {
'user1':{
'2018-04-09': 3,
'2018-04-08': 2,
'2018-04-07': 6,
'2018-04-06': 2,
'2018-04-05': 2,
'2018-04-04': 0,
'2018-04-03': 8
},
'user2': {
'2018-04-09': 1,
'2018-04-08': 0,
'2018-04-07': 5,
'2018-04-06': 0,
'2018-04-05': 0,
'2018-04-04': 0,
'2018-04-03': 0
},
'user3': {
'2018-04-09': 1,
'2018-04-08': 1,
'2018-04-07': 1,
'2018-04-06': 1,
'2018-04-05': 2,
'2018-04-04': 5,
'2018-04-03': 5
},
'user4': {
'2018-04-09': 1,
'2018-04-08': 1,
'2018-04-07': 2,
'2018-04-06': 1,
'2018-04-05': 8,
'2018-04-04': 1,
'2018-04-03': 1
}
}
I have tried splitting up the dict using keys and values. Tried joining multiple dicts. But I am unable to receive the output in the above format.
Based on your experience in Python, can any of you suggest me a way forward or help me in this.
Thanks,
Upvotes: 0
Views: 357
Reputation: 2194
This is what I would do:
user_data = {}
for date in date_wise_data:
for user in date_wise_data[date]:
if user not in user_data:
user_data[user] = {}
user_data[user][date] = date_wise_data[date][user]
note that the keys date
and user
are used in the opposite order in the last line.
Upvotes: 1
Reputation: 18940
First, we flatten the 2-level data you have in date_wise_data
:
>>> flat_data = [(j, k, u) for k, v in date_wise_data.items() for j, u in v.items()]
>>> flat_data.sort() # we sort data for groupby()
>>> flat_data
[('user1', '2018-04-03', 8), ('user1', '2018-04-04', 0), ..., ('user2', '2018-04-03', 0), ...]
Then we use itertools.groupby which "returns consecutive keys and groups from the iterable" (note that groupby require its argument to be sorted to function correctly):
>>> {key: {item[1]: item[2] for item in grouper}
for key, grouper in groupby(flat_data, lambda x: x[0])}
{'user1': {'2018-04-03': 8,
'2018-04-04': 0,
'2018-04-05': 2,
'2018-04-06': 2,
'2018-04-07': 6,
'2018-04-08': 2,
'2018-04-09': 3},
'user2': {'2018-04-03': 0,
'2018-04-04': 0,
'2018-04-05': 0,
'2018-04-06': 0,
'2018-04-07': 5,
'2018-04-08': 0,
'2018-04-09': 1},
'user3': {'2018-04-03': 5,
'2018-04-04': 5,
'2018-04-05': 2,
'2018-04-06': 1,
'2018-04-07': 1,
'2018-04-08': 1,
'2018-04-09': 1},
'user4': {'2018-04-03': 1,
'2018-04-04': 1,
'2018-04-05': 8,
'2018-04-06': 1,
'2018-04-07': 2,
'2018-04-08': 1,
'2018-04-09': 1}}
Upvotes: 1
Reputation: 62
This will do the work:
d = {}
for date in date_wise_data:
for user in date_wise_data[date]:
if user not in d:
d[user]={}
d[user][date] = date_wise_data[date][user]
Upvotes: 0
Reputation: 12052
You can use pandas:
import pandas as pd
df = pd.DataFrame(date_wise_data).transpose()
print(df.head())
# user1 user2 user3 user4
# 2018-04-03 8 0 5 1
# 2018-04-04 0 0 5 1
# 2018-04-05 2 0 2 8
# 2018-04-06 2 0 1 1
# 2018-04-07 6 5 1 2
Convert the dataframe to a dictionary:
print(df.to_dict())
# {'user1': {'2018-04-03': 8, '2018-04-04': 0, '2018-04-05': 2, '2018-04-06': 2, '2018-04-07': 6, '2018-04-08': 2, '2018-04-09': 3}, 'user2': {'2018-04-03': 0, '2018-04-04': 0, '2018-04-05': 0, '2018-04-06': 0, '2018-04-07': 5, '2018-04-08': 0, '2018-04-09': 1}, 'user3': {'2018-04-03': 5, '2018-04-04': 5, '2018-04-05': 2, '2018-04-06': 1, '2018-04-07': 1, '2018-04-08': 1, '2018-04-09': 1}, 'user4': {'2018-04-03': 1, '2018-04-04': 1, '2018-04-05': 8, '2018-04-06': 1, '2018-04-07': 2, '2018-04-08': 1, '2018-04-09': 1}}
Upvotes: 2
Reputation: 88987
The answer to this is relatively simple, just loop through the dictionaries and assign the values to the correct place e.g:
for date, users in date_wise_data.items():
for user, value in users.items():
user_wise_data[user][date] = value
The most awkward part here is that those dictionaries won't exist, so this code won't work. While you could manually check that and construct them, the easier option is to use a defaultdict
to automatically construct them. E.g:
user_wise_data = collections.defaultdict(dict)
This means whenever you try and access a user that doesn't exist, a new dictionary will be created for it. This makes the above code do exactly what you want:
>>> import collections
>>> date_wise_data = {
... '2018-04-09':{
... 'user1': 3,
... 'user2': 1
... },
... '2018-04-08': {
... 'user1': 2,
... 'user2': 0
... }
... }
>>> user_wise_data = collections.defaultdict(dict)
>>>
>>> for date, users in date_wise_data.items():
... for user, value in users.items():
... user_wise_data[user][date] = value
...
>>> user_wise_data
defaultdict(<class 'dict'>, {
'user1': {
'2018-04-09': 3,
'2018-04-08': 2
},
'user2': {
'2018-04-09': 1,
'2018-04-08': 0
}
})
Another option is dict.setdefault()
which allows you to do this at access time, rather than when you set up the dictionary, e.g:
user_wise_data = {}
for date, users in date_wise_data.items():
for user, value in users.items():
user_wise_data.setdefault(user, {})[date] = value
Upvotes: 3
Reputation: 533
I think you may have mistyped your output, as it doesn't correspond to you input. As @pissal comments, the output you requested is not possible.
I guess you want your output to be:
user_data = {
'user1':{
'2018-04-09': 3,
'2018-04-08': 2,
'2018-04-07': 6,
'2018-04-06': 2,
'2018-04-05': 2,
'2018-04-04': 0,
'2018-04-03': 8
},
Then you want code like:
for date, users in date_wise_data.items()
for user, value in users.items()
user_data[user][date] = value
Edited to include : You may need to use defaultdict as specified in @Gareth Latty's answer
Upvotes: 0