Pandas pivot table with column as dictionary

Viewed 1154

I have a dataframe which looks like this. Only order is unique.

vendor  order order_class    time
33       33     42        22/12/2018
33       39     189       25/12/2018
35       197    91        19/01/2019
35       22     189       18/12/2018
35       11     189       30/11/2018

How do I pivot my dataframe to look like this, where the keys are order_class and values are [(order1, time1), (order2, time2)]

vendor   dict
33       {42 : [(33, 25/12/2018)], 189 : [(39, 25/12/2018)]}
35       {91 : [(197, 19/01/2019)], 189: [(22, 18/12/2018), (11, 30/11/2018)]}

*EDITED

An order class can have multiple (order, time) values which needs to be stored in a list.

3 Answers

An alternative approach using groupby, agg and zip:

d1 = df.groupby(['vendor', 'order_class']).agg(list).reset_index(level=1)
d2 = d1.apply(lambda s: {s['order_class']: list(zip(s['order'], s['time']))}, axis=1)
d2 = d2.groupby(level=0).agg(lambda s: {k:v for d in s for k, v in d.items()}).rename('_dict').reset_index()

 #print(d2)
vendor   dict
33       {42 : [(33, 22/12/2018)], 189 : [(39, 25/12/2018)]}
35       {91 : [(197, 19/01/2019)], 189: [(22, 18/12/2018), (11, 30/11/2018)]}

Here is a possible approach by zipping the 3 columns and creating a dict, then using chain we can aggregate them together grouping on the vendor column:

from itertools import chain
f = lambda x: dict(chain(*map( dict.items, x)))

l = [{a:(b,c)} for a,b,c in zip(df['order_class'],df['order'],df['time'])]
pd.Series(l,name='dict_').groupby(df['vendor']).agg(f).reset_index()

   vendor                                              dict_
0      33  {42: (33, '22/12/2018'), 189: (39, '25/12/2018')}
1      35  {91: (197, '19/01/2019'), 189: (22, '18/12/201...
   #Create tuple of order and time

df['dict']=[[x] for x in tuple(zip(df['order'], df['time']))]


#Use groupby, apply .agg(dict) and drop unrequired columns

df.set_index('order_class').groupby('vendor').agg(dict).drop(columns=['time','order']).reset_index()



    vendor     dict
0   33         {42: [(33, '22/12/2018')], 189: [(39, '25/12/2...
1   35         {91: [(197, '19/01/2019')], 189: [[(22, '18/12...
Related