【发布时间】:2022-01-12 15:25:52
【问题描述】:
我在如下所示的数据框中有数据。我正在尝试展平数据,以便 JSON blob 中的值转换为列,如果 JSON blob 中有多个记录,它会创建一个新行。我想保留非 JSON 字段(即 ID)。
我特别关注:How to flatten a pandas dataframe with some columns as json? - 但在执行后,我使用未解析 JSON 的相同数据帧失败。下面是该帖子中的函数的 sn-p,它以前对我有用:
def flatten_nested_json_df(df):
df = df.reset_index()
print(f"original shape: {df.shape}")
print(f"original columns: {df.columns}")
# search for columns to explode/flatten
s = (df.applymap(type) == list).all()
list_columns = s[s].index.tolist()
s = (df.applymap(type) == dict).all()
dict_columns = s[s].index.tolist()
print(f"lists: {list_columns}, dicts: {dict_columns}")
while len(list_columns) > 0 or len(dict_columns) > 0:
new_columns = []
for col in dict_columns:
print(f"flattening: {col}")
# explode dictionaries horizontally, adding new columns
horiz_exploded = pd.json_normalize(df[col]).add_prefix(f'{col}.')
horiz_exploded.index = df.index
df = pd.concat([df, horiz_exploded], axis=1).drop(columns=[col])
new_columns.extend(horiz_exploded.columns) # inplace
for col in list_columns:
print(f"exploding: {col}")
# explode lists vertically, adding new columns
df = df.drop(columns=[col]).join(df[col].explode().to_frame())
new_columns.append(col)
# check if there are still dict o list fields to flatten
s = (df[new_columns].applymap(type) == list).all()
list_columns = s[s].index.tolist()
s = (df[new_columns].applymap(type) == dict).all()
dict_columns = s[s].index.tolist()
print(f"lists: {list_columns}, dicts: {dict_columns}")
print(f"final shape: {df.shape}")
print(f"final columns: {df.columns}")
return df
感谢任何帮助!
| ID | PROPERTIES | FORMSUBMISSIONS |
|---|---|---|
| 123 | {"firstname":{"value":"FAKE"},"lastmodifieddate":{"value":"FAKE"},"lastname":{"value":"FAKE"}} | [{"contact-associated-by":["FAKE"],"conversion-id":"FAKE","form-id":"FAKE","form-type":"FAKE","meta-data":[],"portal-id": FAKE,"timestamp": FAKE,"title":"FAKE"}] |
【问题讨论】:
-
我尝试的每一个方法都出错,'str'对象没有属性'values'或'list'对象没有属性'values' - 我知道我一定缺少一些简单的东西
-
这个错误通常意味着你传递给
pd.json_normalize的是一个列表而不是一个对象。explode在传递给pd.json_normalize之前的列也是如此。另外,请包含您当前拥有的代码,以便人们可以提供帮助。 -
@emma 感谢您的回复 - 刚刚编辑了我的初始帖子以添加我之前一直在尝试的对我有用的功能 - 当我执行
pd.read_json(dataframe["FORMSUBMISSIONS"][0])时,我可以获得所需的结果,但我无法弄清楚如何在数据框中应用它