0

I have a data frame in which I have attributes and values for two products.

PRODUCT ATTRIBUTE   VALUES
prod1   Attr1         A
prod1   Attr2         B
prod1   Attr3         C
prod1   Attr4         D
prod2   Attr1         E
prod2   Attr2         F
prod2   Attr3         G
prod2   Attr4         H

How can I convert it into a dictionary of a list of dictionaries that looks like the following?

{'prod1':[{'Attr1':A, 'Attr2':B, 'Attr3':C, 'Attr4':D}], 'prod2':[{'Attr1':E, 'Attr2':F, 'Attr3':G, 'Attr4':H}]}
EdChum
  • 339,461
  • 188
  • 752
  • 538
Ujjwal Roy
  • 53
  • 1
  • 5

4 Answers4

3

You can use groupby with apply:

d = df.groupby('PRODUCT').apply(lambda x: [dict(zip(x.ATTRIBUTE, x.VALUES))]).to_dict()
print (d)
{'prod1': [{'Attr1': 'A', 'Attr2': 'B', 'Attr3': 'C', 'Attr4': 'D'}],
'prod2': [{'Attr1': 'E', 'Attr2': 'F', 'Attr3': 'G', 'Attr4': 'H'}]}
jezrael
  • 729,927
  • 78
  • 1,141
  • 1,090
2

You can use pandas.DataFrame.pivot to prepare your data and then call pandas.DataFrame.to_dict:

>>> df.pivot(columns='PRODUCT',index='ATTRIBUTE', values='VALUES').to_dict()
{'prod1': {'Attr4': 'D', 'Attr2': 'B', 'Attr3': 'C', 'Attr1': 'A'}, 'prod2': {'Attr4': 'H', 'Attr2': 'F', 'Attr3': 'G', 'Attr1': 'E'}}

I also assume that you don't actually need one-element lists there. In this case you can have really simple solution. If you need those lists then it's probably better to go with @jezrael answer

Roman Pekar
  • 99,839
  • 26
  • 181
  • 193
1

comprehension

{k: [v.to_dict()] for k, v in df.set_index(['PRODUCT', 'ATTRIBUTE']).VALUES.unstack(0).iteritems()}

{'prod1': [{'Attr1': 'A', 'Attr2': 'B', 'Attr3': 'C', 'Attr4': 'D'}],
 'prod2': [{'Attr1': 'E', 'Attr2': 'F', 'Attr3': 'G', 'Attr4': 'H'}]}
piRSquared
  • 265,629
  • 48
  • 427
  • 571
0

Pivot and use the to_dict method and then wrap the inner dict in a list.

d= df.pivot(index='PRODUCT', columns='ATTRIBUTE', values='VALUES').to_dict()
{key:[value] for key,value in d.items()}
Ted Petrou
  • 52,577
  • 18
  • 119
  • 125