24

I have a DataFrame with following columns:

columns = ['Autor', 'Preţul', 'Suprafaţa totală', 'Etaj', 'Etaje', 'Tipul casei', 'Tipul de camere','Numărul de camere','Starea apartamentului', 'Planificare', 'Tipul clădirii', 'Sectorul', 'Strada',  'Numărul casei']
df = pd.DataFrame(columns=columns)

I want to add to this DataFrame a number of dictionaries row by row, for instance for the first row I want to ad this dictionary:

{'Autor': nan,
 'Balcon/lojă': '2',
 'Etaj': '1',
 'Grup sanitar': 'separat',
 'Locul de amplasare în casă': 'In mijlocul casei',
 'Numărul casei': nan,
 'Numărul de camere': '4 şi mai multe camere',
 'Parcare': 'deschisă',
 'Preţul': nan,
 'Sectorul': nan,
 'Strada': nan,
 'Suprafaţa totală': '90 m²',
 'Tipul clădirii': 'Dat în exploatare'}

The values of the keys of the dictionary that are not in the DataFrame columns should be set as NaN values. The dictionaries had only a part of the columns names as keys.

for instance the second dict:

{'Autor': nan,
 'Numărul casei': nan,
 'Numărul de camere': '3 camere',
 'Preţul': nan,
 'Sectorul': nan,
 'Strada': nan,
 'Suprafaţa totală': '103 m²',
 'Tipul clădirii': 'Dat în exploatare'}

The dictionaries are results of a for loop and they should be added as unique row.

Sinchetru
  • 539
  • 1
  • 3
  • 13

3 Answers3

26

Use the pandas.DataFrame.from_dict alternative constructor. Build your "rows" into a list to begin with:

In [22]: import numpy as np

In [23]: nan = np.nan

In [24]: rows = []

In [25]: rows.append({'Autor': nan,
    ...:  'Balcon/lojă': '2',
    ...:  'Etaj': '1',
    ...:  'Grup sanitar': 'separat',
    ...:  'Locul de amplasare în casă': 'In mijlocul casei',
    ...:  'Numărul casei': nan,
    ...:  'Numărul de camere': '4 şi mai multe camere',
    ...:  'Parcare': 'deschisă',
    ...:  'Preţul': nan,
    ...:  'Sectorul': nan,
    ...:  'Strada': nan,
    ...:  'Suprafaţa totală': '90 m²',
    ...:  'Tipul clădirii': 'Dat în exploatare'})

In [26]: rows.append({'Autor': nan,
    ...:  'Numărul casei': nan,
    ...:  'Numărul de camere': '3 camere',
    ...:  'Preţul': nan,
    ...:  'Sectorul': nan,
    ...:  'Strada': nan,
    ...:  'Suprafaţa totală': '103 m²',
    ...:  'Tipul clădirii': 'Dat în exploatare'})

Then, just make sure the pass the appropriate "orient" argument:

In [28]: pd.DataFrame.from_dict(rows, orient='columns')
Out[28]:
   Autor Balcon/lojă Etaj Grup sanitar Locul de amplasare în casă  \
0    NaN           2    1      separat          In mijlocul casei
1    NaN         NaN  NaN          NaN                        NaN

   Numărul casei      Numărul de camere   Parcare  Preţul  Sectorul  Strada  \
0            NaN  4 şi mai multe camere  deschisă     NaN       NaN     NaN
1            NaN               3 camere       NaN     NaN       NaN     NaN

  Suprafaţa totală     Tipul clădirii
0            90 m²  Dat în exploatare
1           103 m²  Dat în exploatare

EDIT

Actually, just noticed the normal constructor works just fine, and doesn't need any arguments!

In [31]: pd.DataFrame(rows)
Out[31]:
   Autor Balcon/lojă Etaj Grup sanitar Locul de amplasare în casă  \
0    NaN           2    1      separat          In mijlocul casei
1    NaN         NaN  NaN          NaN                        NaN

   Numărul casei      Numărul de camere   Parcare  Preţul  Sectorul  Strada  \
0            NaN  4 şi mai multe camere  deschisă     NaN       NaN     NaN
1            NaN               3 camere       NaN     NaN       NaN     NaN

  Suprafaţa totală     Tipul clădirii
0            90 m²  Dat în exploatare
1           103 m²  Dat în exploatare
juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
  • it doesn not work as I need, for instance every dict is a combination of 4 dicts: `z = {**adresa, **d, **pret, **autor}` when I add a nw `z` to the existing list `rows` it rewrite the last dict. The numbers of columns and theirs names should remain the same all the time but they are changing. – Sinchetru Mar 06 '17 at 18:54
  • @Sinchetru I don't see how appending a new `z` to a list would rewrite the last `dict`. That definitely should not happen. What exactly are you doing? – juanpa.arrivillaga Mar 06 '17 at 19:06
  • I found the mistake. I've wrote the `rows = []` in the loop so each time it created a new list. Your answer is the right one. I change the expression to `df = pd.DataFrame(rows, columns=columns)` and the columns name and number are the one that I need. – Sinchetru Mar 06 '17 at 19:11
1

You can loop over the dictionaries, append the results for each dictionary to a list, and then add the list as a row in the DataFrame.

dflist = []
for dic in dictionarylist:
   rlist = []
   for key in keylist:
       if dic[key] is None:
           rlist.append(None)
       else:
           rlist.append(dic[key])

   dflist.append(rlist)

df = pd.DataFrame(dflist)
Michael
  • 13,244
  • 23
  • 67
  • 115
  • I don't think there is any need for all that pre-processing. The `DataFrame` consrtuctors deal with a list of `dict`s just fine. – juanpa.arrivillaga Mar 06 '17 at 18:09
  • I did not know about `pandas.DataFrame.from_dict`, that's cool. This is what that function does effectively, though presumably `DataFrame.from_dict` does it more efficiently. – Michael Mar 06 '17 at 18:11
  • well, as I just discovered, the normal `pd.DataFrame` constructor works just fine as well. – juanpa.arrivillaga Mar 06 '17 at 18:17
0

If your dict data is in a DF column, then the following works well.

recs = []
for index, row in df.iterrows():
    val = ast.literal_eval(row[col_name])
    recs.append(val)

df2 = pd.DataFrame.from_dict(recs)
Flair
  • 2,609
  • 1
  • 29
  • 41
QuentinJS
  • 162
  • 1
  • 9