调用pd.json_normalize处理JSON生成指定列DataFrame报TypeError如何解决
问题修复方案
错误原因
你遇到的TypeError是因为pd.json_normalize的参数使用不符合要求:
- 第二个参数
record_path作用是指定需要展开的嵌套数组路径,你的需求是展开每个播放列表下的tracks数组,所以该参数应填['tracks'],不能把所有待提取字段都放到这个参数里 - 第三个参数
meta用于指定每条展开后的记录需要附带的上层字段,info是JSON顶级字段,不属于playlists数组的子字段,不能直接传入js['info'],需要明确写出字段层级
另外你原有代码还存在两个逻辑问题:
- 循环读取多文件的逻辑有误,循环内每次读取的JSON内容会覆盖
js变量,最终只会处理最后一个匹配的JSON文件 - 播放列表层级和单曲层级都有名为
duration_ms的字段,需要添加前缀区分避免后续字段覆盖
修复后完整代码
import json import pandas as pd import os path = 'C:\\Users\\sotir\\Desktop\\machinedataset' # 存储所有文件解析后的结果 all_data = [] filenames = os.listdir(path) for filename in sorted(filenames): if filename.startswith("mpd.slice.") and filename.endswith(".json"): fullpath = os.path.join(path, filename) with open(fullpath, 'r', encoding='utf-8') as f: js = json.load(f) # 解析当前文件 df = pd.json_normalize( data=js['playlists'], record_path='tracks', # 指定要展开的tracks嵌套数组 # 附加的playlist层级指定字段 meta=[ 'name', 'collaborative', 'pid', 'modified_at', 'num_tracks', 'num_albums', 'num_followers', 'num_edits', 'duration_ms', 'num_artists' ], record_prefix='track_' # 给track层级字段加前缀,避免和playlist的duration_ms重名 ) # 手动添加info层级的指定字段 df['generated_on'] = js['info']['generated_on'] df['slice'] = js['info']['slice'] df['version'] = js['info']['version'] all_data.append(df) # 合并所有文件的解析结果 final_df = pd.concat(all_data, ignore_index=True) # 按你要求的顺序重新排列字段 final_df = final_df[[ # playlist字段 'name', 'collaborative', 'pid', 'modified_at', 'num_tracks', 'num_albums', 'num_followers', 'num_edits', 'duration_ms', 'num_artists', # track字段 'track_pos', 'track_artist_name', 'track_track_uri', 'track_artist_uri', 'track_track_name', 'track_album_uri', 'track_duration_ms', 'track_album_name', # info字段 'generated_on', 'slice', 'version' ]]
结果说明
运行后得到的final_df就是符合要求的结构化表格,每一行对应一首单曲,同时附带所属播放列表、当前JSON切片的所有指定字段。如果不需要track_前缀,也可以自行重命名字段。
内容的提问来源于stack exchange,提问作者manduk
相关产品推荐
相关产品推荐

