Data Mastery
Data Mastery

Reputation: 2095

Pandas way to create new dataframe from rows which contain list of dictionaries

I have the following dataFrame.

    ID  APs
0   1   [{'ID': -1, 'Name': 'Merkmal nicht erhoben'}, {'ID': 0, 'Name': 'Nicht bekannt'}, {'ID': 1, 'Name': 'Werbung bekannt'}, {'ID': 2, 'Name': 'Werbung unbekannt, aber Marke/Modell bekannt'}]
1   2   [{'ID': -1, 'Name': 'Merkmal nicht erhoben'}, {'ID': 0, 'Name': 'Nicht bekannt'}, {'ID': 1, 'Name': 'Bin dort Kunde'}, {'ID': 2, 'Name': 'Käme auch noch in Frage'}, {'ID': 3, 'Name': 'Käme eher nicht in Frage'}, {'ID': 4, 'Name': 'Käme bestimmt nicht in Frage'}]
2   3   [{'ID': -1, 'Name': 'Merkmal nicht erhoben'}, {'ID': 0, 'Name': 'Nicht bekannt'}, {'ID': 1, 'Name': 'Nein'}, {'ID': 2, 'Name': 'Ja'}]
3   4   [{'ID': -1, 'Name': 'Merkmal nicht erhoben'}, {'ID': 0, 'Name': 'Nicht bekannt'}, {'ID': 1, 'Name': 'Sehr sympathisch'}, {'ID': 2, 'Name': 'Sympathisch'}, {'ID': 3, 'Name': 'Weniger sympathisch'}, {'ID': 4, 'Name': 'Überhaupt nicht sympathisch'}]
4   5   [{'ID': -1, 'Name': 'Merkmal nicht erhoben'}, {'ID': 0, 'Name': 'Nicht bekannt'}, {'ID': 1, 'Name': 'Käme in die engere Wahl'}, {'ID': 2, 'Name': 'käme auch noch in Frage'}, {'ID': 3, 'Name': 'Käme eher nicht in Frage'}, {'ID': 4, 'Name': 'Käme nicht in Frage'}]
5   6   [{'ID': -1, 'Name': 'Merkmal nicht erhoben'}, {'ID': 0, 'Name': 'Nicht bekannt'}, {'ID': 1, 'Name': 'Nein'}, {'ID': 2, 'Name': 'Ja'}]
6   7   [{'ID': -1, 'Name': 'Merkmal nicht erhoben'}, {'ID': 0, 'Name': 'Nicht bekannt'}, {'ID': 1, 'Name': 'Bestimmt empfehlen'}, {'ID': 2, 'Name': 'Eher empfehlen'}, {'ID': 3, 'Name': 'Eher nicht empfehlen'}, {'ID': 4, 'Name': 'Bestimmt nicht empfehlen'}]
7   8   [{'ID': -1, 'Name': 'Merkmal nicht erhoben'}, {'ID': 0, 'Name': 'Nicht bekannt'}, {'ID': 1, 'Name': 'Nein / nicht bekannt'}, {'ID': 2, 'Name': 'Ja'}]
8   9   [{'ID': -1, 'Name': 'Merkmal nicht erhoben'}, {'ID': 0, 'Name': 'Nicht bekannt'}, {'ID': 1, 'Name': 'Nein'}, {'ID': 2, 'Name': 'Ja'}]

It contains a column with a dictionary, which i also want to have in a dataframe format. I could do something like this to build a dataframe for each ID and than use pd.concat.

desired = pd.DataFrame(kpi_df["APs"][0])
desired["df_id"] = 1

   ID                                          Name  df_id
0  -1                         Merkmal nicht erhoben      1
1   0                                 Nicht bekannt      1
2   1                               Werbung bekannt      1
3   2  Werbung unbekannt, aber Marke/Modell bekannt      1

I could write a loop to do this for all rows. This seems to be quite difficult and error prone. Is there a better way to handle this kind of nested data?

Upvotes: 0

Views: 50

Answers (1)

BENY
BENY

Reputation: 323376

Let us try explode both on row and columns then join

s = df.pop('APs').explode()
out = pd.DataFrame(s.tolist(),index=s.index).join(df.rename(columns={'ID':'df_id'}))
out
Out[342]: 
   ID                                          Name  df_id
0  -1                         Merkmal nicht erhoben      1
0   0                                 Nicht bekannt      1
0   1                               Werbung bekannt      1
0   2  Werbung unbekannt, aber Marke/Modell bekannt      1
1  -1                         Merkmal nicht erhoben      2
1   0                                 Nicht bekannt      2
1   1                                Bin dort Kunde      2
1   2                       Käme auch noch in Frage      2
1   3                      Käme eher nicht in Frage      2
1   4                  Käme bestimmt nicht in Frage      2

Upvotes: 1

Related Questions