Pandas DataFrame嵌套列表字典提取:hours列拆分与处理优化
处理嵌套JSON数据生成Pandas DataFrame:拆分Hours列及高效嵌套列处理方案
一、获取原始数据并初始化DataFrame
先通过接口拉取数据并转换为基础DataFrame:
import pandas as pd import requests response = requests.get("https://www.coloradobrewerylist.com/wp-json/cbl_api/v1/locations/?location-type%5Bnin%5D=404,405&page_size=1000&page_token=1") data = response.json() df = pd.DataFrame(data)
二、拆分Hours列为Mon_Hours至Sun_Hours
针对hours列的嵌套字典列表结构,通过自定义函数提取每日营业时间并合并到原表:
def extract_hours(hours_list): hours_dict = {} day_map = { 'Monday': 'Mon_Hours', 'Tuesday': 'Tue_Hours', 'Wednesday': 'Wed_Hours', 'Thursday': 'Thu_Hours', 'Friday': 'Fri_Hours', 'Saturday': 'Sat_Hours', 'Sunday': 'Sun_Hours' } for item in hours_list: day = item.get('day') hours = item.get('hours') if day in day_map: hours_dict[day_map[day]] = hours return pd.Series(hours_dict) # 提取营业时间并合并 hours_df = df['hours'].apply(extract_hours) df = pd.concat([df.drop('hours', axis=1), hours_df], axis=1)
缺失营业时间的日期会自动填充NaN,保持数据结构一致性。
三、高效处理不同长度的嵌套列(以memberships为例)
针对嵌套列表长度不一致的列,可根据业务需求选择两种处理方式:
方式1:展开为多行(保留所有明细)
适合需要分析嵌套字段每条记录的场景,通过explode+json_normalize实现:
from pandas import json_normalize # 展开memberships列表为单行对应一条明细 exploded_df = df.explode('memberships', ignore_index=True) # 解析嵌套字典为结构化列 memberships_normalized = json_normalize(exploded_df['memberships']) # 合并到原表 df_expanded = pd.concat([exploded_df.drop('memberships', axis=1), memberships_normalized], axis=1)
方式2:聚合为摘要(保持原始行数)
适合需要快速查看嵌套内容摘要、不想拆分数据行数的场景:
# 聚合为逗号分隔的文本摘要 df['memberships_summary'] = df['memberships'].apply( lambda x: ', '.join([f"{m.get('name')}: {m.get('description')}" for m in x]) if x else None ) # 或保留结构化列表(方便后续二次处理) df['memberships_list'] = df['memberships'].apply( lambda x: [{k: v for k, v in m.items() if k in ['name', 'description']} for m in x] if x else None )
完整代码示例
import pandas as pd import requests from pandas import json_normalize # 1. 获取数据 response = requests.get("https://www.coloradobrewerylist.com/wp-json/cbl_api/v1/locations/?location-type%5Bnin%5D=404,405&page_size=1000&page_token=1") data = response.json() df = pd.DataFrame(data) # 2. 拆分hours列 def extract_hours(hours_list): hours_dict = {} day_map = { 'Monday': 'Mon_Hours', 'Tuesday': 'Tue_Hours', 'Wednesday': 'Wed_Hours', 'Thursday': 'Thu_Hours', 'Friday': 'Fri_Hours', 'Saturday': 'Sat_Hours', 'Sunday': 'Sun_Hours' } for item in hours_list: day = item.get('day') hours = item.get('hours') if day in day_map: hours_dict[day_map[day]] = hours return pd.Series(hours_dict) hours_df = df['hours'].apply(extract_hours) df = pd.concat([df.drop('hours', axis=1), hours_df], axis=1) # 3. 处理memberships列(二选一) # 方式一:展开为多行 exploded_df = df.explode('memberships', ignore_index=True) memberships_normalized = json_normalize(exploded_df['memberships']) df_expanded = pd.concat([exploded_df.drop('memberships', axis=1), memberships_normalized], axis=1) # 方式二:生成摘要列 df['memberships_summary'] = df['memberships'].apply( lambda x: ', '.join([f"{m.get('name')}: {m.get('description')}" for m in x]) if x else None )
内容的提问来源于stack exchange,提问作者BenW
相关产品推荐
相关产品推荐

