如何从Pandas DataFrame的字符串字典列提取指定字段为新列?
提取DataFrame字符串列中的字典字段为新列
问题背景
现有DataFrame df 的events列存储的是字符串形式的字典,示例数据如下:
| events |
|---|
| {'id': 109421132110384, 'created_at': datetime.datetime(2022, 11, 28, 11, 12, 50, tzinfo=tzutc()), 'in_reply_to_id': None, ...} |
| {'id': 109421132340384, 'created_at': datetime.datetime(2022, 11, 30, 11, 12, 50, tzinfo=tzutc()), 'in_reply_to_id': None, ...} |
尝试直接通过df['events'][0]['id']取值时,触发错误:TypeError: string indices must be integers,因为events列的元素类型是str,而非Python字典。
解决方案
核心思路是先将字符串解析为字典,再提取目标字段。以下是两种可靠实现方式:
方法1:使用ast.literal_eval解析后逐字段提取
ast.literal_eval是安全的字符串转字典工具(避免eval的安全风险),适合处理标准格式的字符串字典:
import ast import pandas as pd # 将字符串转为字典 df['events_dict'] = df['events'].apply(ast.literal_eval) # 提取目标字段作为新列 df['id'] = df['events_dict'].apply(lambda x: x['id']) df['created_at'] = df['events_dict'].apply(lambda x: x['created_at']) df['in_reply_to_id'] = df['events_dict'].apply(lambda x: x['in_reply_to_id']) # 可选:删除中间辅助列 df = df.drop('events_dict', axis=1)
方法2:结合ast.literal_eval与pd.json_normalize批量提取
适合一次性提取多个字段,代码更简洁:
import ast import pandas as pd # 解析所有字符串为字典列表 events_data = df['events'].apply(ast.literal_eval).tolist() # 规范化字典列表为DataFrame,并合并到原表 df = df.join(pd.json_normalize(events_data)[['id', 'created_at', 'in_reply_to_id']])
特殊情况处理:含Python对象的字符串字典
如果字符串中包含datetime.datetime这类Python对象(如示例中的created_at值),ast.literal_eval无法直接解析,可通过替换字符串后再解析:
import ast from datetime import datetime, timezone def parse_event(s): # 替换字符串中的Python对象标识为可解析格式 s = s.replace('datetime.datetime', 'datetime').replace('tzutc()', 'timezone.utc') return ast.literal_eval(s) df['events_dict'] = df['events'].apply(parse_event) # 后续字段提取步骤同方法1
内容的提问来源于stack exchange,提问作者deepu2711
相关产品推荐
相关产品推荐

