Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populating a pandas dataframe from an odd dictionary

I have a dictionary as follows:

{'header_1': ['body_1', 'body_3', 'body_2'],
 'header_2': ['body_6', 'body_4', 'body_5'],
 'header_4': ['body_7', 'body_8'],
 'header_3': ['body_9'],
 'header_9': ['body_10'],
 'header_10': []}

I would like to come up with a dataframe like this:

+----+----------+--------+
| ID | header   | body   |
+----+----------+--------+
| 1  | header_1 | body_1 |
+----+----------+--------+
| 2  | header_1 | body_3 |
+----+----------+--------+
| 3  | header_1 | body_2 |
+----+----------+--------+
| 4  | header_2 | body_6 |
+----+----------+--------+
| 5  | header_2 | body_4 |
+----+----------+--------+
| 6  | header_2 | body_5 |
+----+----------+--------+
| 7  | header_4 | body_7 |
+----+----------+--------+

Where blank items (such as for the key header_10 in the dict above) would receive a value of None. I have tried a number of varieties for df.loc such as:

for header_name, body_list in all_unique.items():
    for body_name in body_list:
        metadata.loc[metadata.index[-1]] = [header_name, body_name]

To no avail. Surely there must be a quick way in Pandas to append rows and autoincrement the index? Something similar to the SQL INSERT INTO statement only using pythonic code?

like image 799
user32882 Avatar asked Dec 30 '25 01:12

user32882


2 Answers

Use dict comprehension for add Nones for empty lists and then flatten for list of tuples:

d = {'header_1': ['body_1', 'body_3', 'body_2'],
 'header_2': ['body_6', 'body_4', 'body_5'],
 'header_4': ['body_7', 'body_8'],
 'header_3': ['body_9'],
 'header_9': ['body_10'],
 'header_10': []}

d = {k: v if bool(v) else [None] for k, v in d.items()}
data = [(k, y) for k, v in d.items() for y in v]
df = pd.DataFrame(data, columns= ['a','b'])
print (df)
            a        b
0    header_1   body_1
1    header_1   body_3
2    header_1   body_2
3    header_2   body_6
4    header_2   body_4
5    header_2   body_5
6    header_4   body_7
7    header_4   body_8
8    header_3   body_9
9    header_9  body_10
10  header_10     None

Another solution:

data = []
for k, v in d.items():
    if bool(v):
        for y in v:
            data.append((k, y))
    else:
        data.append((k, None))


df = pd.DataFrame(data, columns= ['a','b'])
print (df)
            a        b
0    header_1   body_1
1    header_1   body_3
2    header_1   body_2
3    header_2   body_6
4    header_2   body_4
5    header_2   body_5
6    header_4   body_7
7    header_4   body_8
8    header_3   body_9
9    header_9  body_10
10  header_10     None
like image 151
jezrael Avatar answered Jan 01 '26 17:01

jezrael


If the dataset is too big, this solution would be slow, but it should still work.

for key in data.keys():
    vals= data[key]
    # Create temp df with data from a single key
    t_df = pd.DataFrame({'header':[key]*len(vals),'body':vals})

    # Append it to your full dataframe.
    df = df.append(t_df)
like image 27
Polkaguy6000 Avatar answered Jan 01 '26 17:01

Polkaguy6000