- This question is specific to columns of data in a
pandas.DataFrame
- This question depends on if the values in the columns are
str
,dict
, orlist
type. - This question addresses dealing with the
NaN
values, whendf.dropna().reset_index(drop=True)
isn't a valid option.
Case 1
- With a column of
str
type, the values in the column must be converted todict
type, withast.literal_eval
, before using.json_normalize
.
import numpy as np
import pandas as pd
from ast import literal_eval
df = pd.DataFrame({'col_str': ['{"a": "46", "b": "3", "c": "12"}', '{"b": "2", "c": "7"}', '{"c": "11"}', np.NaN]})
col_str
0 {"a": "46", "b": "3", "c": "12"}
1 {"b": "2", "c": "7"}
2 {"c": "11"}
3 NaN
type(df.iloc[0, 0])
[out]: str
df.col_str.apply(literal_eval)
Error:
df.col_str.apply(literal_eval) results in ValueError: malformed node or string: nan
Case 2
- With a column of
dict
type, usepandas.json_normalize
to convert keys to column headers and values to rows
df = pd.DataFrame({'col_dict': [{"a": "46", "b": "3", "c": "12"}, {"b": "2", "c": "7"}, {"c": "11"}, np.NaN]})
col_dict
0 {'a': '46', 'b': '3', 'c': '12'}
1 {'b': '2', 'c': '7'}
2 {'c': '11'}
3 NaN
type(df.iloc[0, 0])
[out]: dict
pd.json_normalize(df.col_dict)
Error:
pd.json_normalize(df.col_dict) results in AttributeError: 'float' object has no attribute 'items'
Case 3
- In a column of
str
type, with thedict
inside alist
. - To normalize the column
- apply
literal_eval
, because explode doesn't work onstr
type - explode the column to separate the
dicts
to separate rows - normalize the column
- apply
df = pd.DataFrame({'col_str': ['[{"a": "46", "b": "3", "c": "12"}, {"b": "2", "c": "7"}]', '[{"b": "2", "c": "7"}, {"c": "11"}]', np.nan]})
col_str
0 [{"a": "46", "b": "3", "c": "12"}, {"b": "2", "c": "7"}]
1 [{"b": "2", "c": "7"}, {"c": "11"}]
2 NaN
type(df.iloc[0, 0])
[out]: str
df.col_str.apply(literal_eval)
Error:
df.col_str.apply(literal_eval) results in ValueError: malformed node or string: nan