Home > Software engineering >  How can I convert a dict of arrays into a 'flattened' dataframe?
How can I convert a dict of arrays into a 'flattened' dataframe?

Time:05-15

Let's say I had a dictionary of arrays, eg:

favourite_icecreams = {
    'Josh': ['vanilla', 'banana'],
    'Greg': ['chocolate'],
    'Sarah': ['mint', 'vanilla', 'mango']
}

I want to convert it to a pandas dataframe, with columns as "Flavour" and "Person". It should look like this:

Flavour Person
vanilla Josh
banana Josh
chocolate Greg
mint Sarah
vanilla Sarah
mango Sarah

What's the most efficient way to do this?

CodePudding user response:

You can use (generator) comprehension and then feed it to pd.DataFrame:

import pandas as pd

favourite_icecreams = {
    'Josh': ['vanilla', 'banana'],
    'Greg': ['chocolate'],
    'Sarah': ['mint', 'vanilla', 'mango']
}

data = ((flavour, person)
            for person, flavours in favourite_icecreams.items()
            for flavour in flavours)
df = pd.DataFrame(data, columns=('Flavour', 'Person'))

print(df)
     # Flavour Person
# 0    vanilla   Josh
# 1     banana   Josh
# 2  chocolate   Greg
# 3       mint  Sarah
# 4    vanilla  Sarah
# 5      mango  Sarah

CodePudding user response:

You can do this purely in pandas like below using DataFrame.from_dict and df.stack:

In [453]: df = pd.DataFrame.from_dict(favourite_icecreams, orient='index').stack().reset_index().drop('level_1', 1)

In [455]: df.columns = ['Person', 'Flavour']

In [456]: df
Out[456]: 
  Person    Flavour
0   Josh    vanilla
1   Josh     banana
2   Greg  chocolate
3  Sarah       mint
4  Sarah    vanilla
5  Sarah      mango

CodePudding user response:

One option is to extract person and flavour into separate lists, use numpy repeat on the person list, and finally create the DataFrame:

from itertools import chain
person, flavour = zip(*favourite_icecreams.items())
lengths = list(map(len, flavour))
person = np.array(person).repeat(lengths)
flavour = chain.from_iterable(flavour)
pd.DataFrame({'person':person, 'flavour':flavour})

  person    flavour
0   Josh    vanilla
1   Josh     banana
2   Greg  chocolate
3  Sarah       mint
4  Sarah    vanilla
5  Sarah      mango
  • Related