Sreenath
Sreenath

Reputation: 143

Generate a dictionary from another dictionary

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

Answers (6)

Aemyl
Aemyl

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

fferri
fferri

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

s.singh
s.singh

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

Darius
Darius

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

Gareth Latty
Gareth Latty

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

EdR
EdR

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

Related Questions