
本文介绍如何在 python 中安全地将 dataframe 中存储为字符串的字典(如 `"{827056812014862: [0.05, 0.0608, 0.476464, 0.53535]}"`)解析为结构化表格,提取键为 `id`、列表元素依次映射为 `t1`, `t2`, `t3`, `t4` 等独立列。
在实际数据处理中,常遇到将嵌套结构以字符串形式存储于单列的情况(例如日志导出、API 响应或低规范数据库导出)。直接使用 eval() 解析存在严重安全风险,推荐使用 ast.literal_eval() —— 它仅支持安全的字面量(如 dict、list、float、int、str),可有效防止代码注入。
以下是一个完整、健壮的解决方案:
import pandas as pd
from ast import literal_eval
# 示例原始数据
df = pd.DataFrame({
"column_A": [
"{827056812014862: [0.05, 0.0608, 0.476464, 0.53535]}",
"{263746262748835: [0.08, 0.0333, 0.8263, 0.9463]}",
"{63673738736362: [0.05, 0.0926, 0.8694, 0.9903]}",
"{73737681201484: [0.08, 0.0425, 0.1948, 0.3958]}"
]
})
# 安全解析 + 展开为标准 DataFrame
records = []
for s in df["column_A"]:
try:
d = literal_eval(s) # 安全转换字符串为 dict
for key, values in d.items():
if isinstance(values, (list, tuple)) and len(values) == 4:
records.append({
"id": key,
"t1": values[0],
"t2": values[1],
"t3": values[2],
"t4": values[3]
})
else:
raise ValueError(f"Unexpected value format: {values}")
except (ValueError, SyntaxError) as e:
print(f"Warning: Skipping invalid string '{s}' — {e}")
continue
result = pd.DataFrame(records)
print(result)✅ 输出结果与预期一致:
id t1 t2 t3 t4 0 827056812014862 0.05 0.0608 0.476464 0.53535 1 263746262748835 0.08 0.0333 0.826300 0.94630 2 63673738736362 0.05 0.0926 0.869400 0.99030 3 73737681201484 0.08 0.0425 0.194800 0.39580
? 关键注意事项:
- ✅ 永远避免 eval():它可执行任意 Python 表达式,存在严重安全隐患;literal_eval() 是唯一推荐替代方案。
- ⚠️ 添加异常处理:真实数据中可能存在格式错误、空值或长度不一致的列表,务必用 try/except 包裹解析逻辑。
- ? 扩展性建议:若列表长度不固定,可用 **{f"t{i}": v for i, v in enumerate(values, 1)} 动态生成列名(如答案中所示),再通过 pd.json_normalize() 或 pd.concat() 统一列结构。
- ? 性能优化(大数据量):对超大规模数据,可改用 apply + pd.Series 向量化展开(需确保每行仅含一个 key-value 对),但需注意内存开销。
该方法兼顾安全性、可读性与工程鲁棒性,适用于 ETL 流程、数据清洗及 Pandas 标准化预处理场景。










