如何用Pandas高效矢量化解析关系数据库中的嵌套JSON数据
高效解析Pandas中嵌套字典列表的方案
针对你从Baserow API获取的DataFrame中,部分列包含字典列表(或空列表)的情况,以下是几种无需两层循环的高效处理方案,性能远优于手动遍历:
方案1:apply + 列表推导式(简单直观,中等数据量首选)
利用Pandas的apply方法结合Python原生列表推导式,直接对每个单元格的列表进行解析,自动处理空列表:
import pandas as pd # 构造示例数据 data = { 'target_col': [ [{'id': 1207327, 'value': 'foo'}, {'id': 1207330, 'value': 'bar'}], [], [{'id': 1207331, 'value': 'baz'}] ] } df = pd.DataFrame(data) # 提取value为列表 df['value_list'] = df['target_col'].apply(lambda x: [d['value'] for d in x] if x else []) # 若需要转成逗号分隔的字符串 df['value_str'] = df['target_col'].apply(lambda x: ','.join([d['value'] for d in x]) if x else '')
这个方案代码简洁,列表推导式是Python原生高效操作,比两层循环快数倍,适合大多数日常场景。
方案2:explode + json_normalize + groupby(大数据量最优)
当数据量较大时,用Pandas的矢量化爆炸、归一化和分组聚合操作,完全规避Python层面循环:
# 处理单列数据 # 1. 爆炸列表,把每个字典拆成单独行 exploded_df = df.explode('target_col') # 2. 归一化字典,提取id和value列 normalized_df = pd.json_normalize(exploded_df['target_col']).dropna() # dropna处理空列表爆炸后的NaN # 3. 按原索引分组,聚合value为列表 value_lists = normalized_df.groupby(normalized_df.index)['value'].agg(list) # 4. 补回原数据中为空列表的行,填充空列表 df['value_list'] = value_lists.reindex(df.index, fill_value=[]) # 转成字符串的话,把agg(list)改成agg(','.join)即可 df['value_str'] = normalized_df.groupby(normalized_df.index)['value'].agg(','.join).reindex(df.index, fill_value='')
该方案依赖Pandas底层优化的C代码执行,数据量越大,对比循环的性能优势越明显。
方案3:numpy vectorize(多列批量处理)
如果需要同时处理多列,用numpy的向量化函数封装解析逻辑,一次性处理所有目标列:
import numpy as np # 定义解析函数 def extract_values(lst): return [d['value'] for d in lst] if lst else [] # 向量化封装(指定返回类型为object,因为返回的是列表) vectorized_extractor = np.vectorize(extract_values, otypes=[object]) # 批量处理多列 target_cols = ['col1', 'col2'] # 替换成你的目标列名 df[[f'{col}_values' for col in target_cols]] = pd.DataFrame( vectorized_extractor(df[target_cols].values), index=df.index )
这个方法适合需要批量处理多列的场景,代码复用性强。
内容的提问来源于stack exchange,提问作者Sereios
相关产品推荐
相关产品推荐

