pd.DataFrame传入含空metrics列表的字典返回空行的解决问题
问题原因
空白DataFrame是pandas的默认构造逻辑导致的:传入字典构造DataFrame时,字典内的列表类型值会被识别为多行数据源,其余标量字段会自动广播到和列表长度一致的行数。当
metrics为长度为0的空列表时,pandas会对齐生成0行数据,其余标量字段全部被丢弃。
运行效果示意:
解决方案
分两种常见需求场景处理:
场景1:不需要展开metrics内容,所有字段保留为1行,metrics列直接存储原列表
直接将完整数据字典包装在列表中传入pd.DataFrame()即可,pandas会将整个字典识别为单行数据,列表类型的metrics会作为单个元素存入对应列:
import pandas as pd data = {'genre': 'Pop', 'country': 'CA', 'artist_name': 'Olivia Rodrigo', 'title_name': 'good 4 u', 'release_date': '2021-05-13', 'core_genre': 'Pop', 'metrics': [], 'week_id': 202101, 'top_isrc': 'USUG12101245'} # 核心修改:外层加[]包裹字典 df = pd.DataFrame([data])
运行后得到1行数据,metrics列存储空列表,无数据丢失。
场景2:兼容metrics非空时展开为多行、metrics为空时保留1行的需求
封装构造逻辑,对空metrics做特殊处理即可:
def build_metric_df(raw_data): # 取出metrics字段单独处理 metric_list = raw_data.pop('metrics') if not metric_list: # 空metrics场景:生成1行基础数据,metrics列赋值空列表 df = pd.DataFrame([raw_data]) df['metrics'] = [[]] return df # 非空metrics场景:按原逻辑展开为多行 df = pd.DataFrame(raw_data, index=range(len(metric_list))) df['metrics'] = metric_list return df # 测试空metrics数据 data1 = {'genre': 'Pop', 'country': 'CA', 'artist_name': 'Olivia Rodrigo', 'title_name': 'good 4 u', 'release_date': '2021-05-13', 'core_genre': 'Pop', 'metrics': [], 'week_id': 202101, 'top_isrc': 'USUG12101245'} df1 = build_metric_df(data1) # 测试非空metrics数据 data2 = {'genre': 'Pop', 'country': 'CA', 'artist_name': 'Olivia Rodrigo', 'title_name': 'drivers license', 'release_date': '2021-01-07', 'core_genre': 'Pop', 'metrics': [{'name': 'Song w/SES On-Demand', 'value': [{'name': 'tp', 'value': 1}, {'name': 'lp', 'value': 0}, {'name': 'ytd', 'value': 1}, {'name': 'atd', 'value': 1}]}, {'name': 'Song w/SES On-Demand Audio', 'value': [{'name': 'tp', 'value': 0}, {'name': 'lp', 'value': 0}, {'name': 'ytd', 'value': 0}, {'name': 'atd', 'value': 0}]}, {'name': 'Streaming On-Demand Total', 'value': [{'name': 'tp', 'value': 414}, {'name': 'lp', 'value': 0}, {'name': 'ytd', 'value': 414}, {'name': 'atd', 'value': 414}]}, {'name': 'Streaming On-Demand Audio', 'value': [{'name': 'tp', 'value': 69}, {'name': 'lp', 'value': 0}, {'name': 'ytd', 'value': 69}, {'name': 'atd', 'value': 69}]}], 'week_id': 202101, 'top_isrc': 'USUG12004749'} df2 = build_metric_df(data2)
该方案下,空metrics会生成1行数据,非空metrics会按列表长度生成对应行数,完全不会丢失基础字段数据。
内容的提问来源于stack exchange,提问作者Canovice
相关产品推荐
相关产品推荐


