You can use .explode() to expand the list of dict in column categories into separate rows, then create the categories names ('categories 1', 'categories 2', etc) by grouping on the original row index (row index before explode) using .groupby() and get the serial number by .cumcount() within the group. Finally, we use .pivot() to pivot the rows into columns.
df1 = df.explode('categories') df1['Cat_Num'] = 'categories ' + df1.groupby(level=0).cumcount().add(1).astype(str) df2 = df1.pivot(columns='Cat_Num', values='categories').rename_axis(columns=None)
Demo
data = {'categories': [ [{ "S" : "Vibes" }, { "S" : "Themed" }, { "S" : "Experiences" }, { "S" : "Girls Night" }], [ { "S" : "Vibes" }], [ { "S" : "Vibes" }, { "S" : "Drinks" }] ]} df = pd.DataFrame(data) df1 = df.explode('categories') df1['Cat_Num'] = 'categories ' + df1.groupby(level=0).cumcount().add(1).astype(str) df2 = df1.pivot(columns='Cat_Num', values='categories').rename_axis(columns=None) print(df2) categories 1 categories 2 categories 3 categories 4 0 {'S': 'Vibes'} {'S': 'Themed'} {'S': 'Experiences'} {'S': 'Girls Night'} 1 {'S': 'Vibes'} NaN NaN NaN 2 {'S': 'Vibes'} {'S': 'Drinks'} NaN NaN