to_dict() 的 orient 参数取值有 'dict'(默认)、'list'、'records'、'index'、'series';其中 'records' 生成字典列表,最常用且适配 json;'index' 以行索引为外层 key,需注意索引类型;'list' 和 'series' 分别返回列名到值列表、series 的映射;复杂类型需预处理。

to_dict() 的 orient 参数到底有哪些取值
to_dict() 默认行为是 orient='dict',即列名为 key,对应列为 value(Series),这在多数下游处理中并不直接可用。真正实用的取值是:'list'、'records'、'index' 和 'series'。
其中:'records' 生成每行一个字典的列表,最贴近“把表转成字典集合”的直觉;'index' 把行索引作为外层 key,适合需要按 ID 查找整行的场景;'list' 是列名 → 值列表映射,适合批量取某一列所有值;'series' 返回列名 → Series 映射,保留 dtype 和索引信息,但不是纯 Python 字典。
常见错误:误用 orient='dict' 后直接 json.dumps(),会报 TypeError: Object of type Series is not JSON serializable —— 因为 value 是 Series 而非 list 或 dict。
想导出为 [{}, {}, ...] 格式?必须用 orient='records'
这是最常被搜索的用例:把 DataFrame 每一行转成一个独立字典,最终得到一个字典列表。例如原始数据:
import pandas as pd
df = pd.DataFrame({'name': ['Alice', 'Bob'], 'age': [25, 30]})
df.to_dict(orient='records')
输出为:[{'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}]。
- 该格式可直接传给
requests.post(json=...)或写入 JSON 文件 - 注意:NaN 值会变成
None,若需字符串占位(如空字符串),得先df.fillna('') - 如果 DataFrame 有重复列名,
orient='records'仍能运行,但字典 key 会覆盖 —— pandas 不报错,结果不可靠
用 orient='index' 时,索引类型会影响字典 key
当 DataFrame 索引是整数(默认 RangeIndex)或字符串,orient='index' 输出的外层 key 就是对应索引值:
df = pd.DataFrame([[1, 2], [3, 4]], columns=['a', 'b'])
df.to_dict(orient='index')
# → {0: {'a': 1, 'b': 2}, 1: {'a': 3, 'b': 4}}
但如果索引是 datetime 或 tuple 类型,key 会是原生 Python 对象(如 datetime.date(2023, 1, 1)),此时若后续要 JSON 序列化,会再次触发 TypeError。
- 解决办法:先统一转为字符串索引,
df.index = df.index.astype(str) - 或者改用
orient='records'+ 手动加 id 字段,更可控 - 别依赖
orient='index'的 key 做前端下拉选项的 value —— 非字符串索引可能引发渲染异常
to_dict() 不递归处理嵌套结构,复杂类型会丢失
如果 DataFrame 某列包含 list、dict 或自定义对象(比如 datetime.datetime),to_dict() 默认不做序列化转换,而是原样保留引用或调用 __repr__() —— 导致输出不可预测。
例如:
df = pd.DataFrame({'tags': [[1, 2], {'x': 3}]})
df.to_dict(orient='records') # → [{'tags': [1, 2]}, {'tags': {'x': 3}}]
看起来正常,但若列中混有 numpy.int64 或 pd.Timestamp,就会出现 TypeError 或奇怪字符串(如 '2023-01-01T00:00:00.000000000')。
- 安全做法:对含复杂类型的列,先用
df[col].apply(lambda x: x.tolist() if hasattr(x, 'tolist') else x)清洗 - 或统一走
df.astype(object).to_dict(orient='records'),但注意这会丢失数值精度(如 float 变成 Python float) - 真正需要深度序列化的场景,建议用
df.to_json(orient='records')+json.loads(),它内置了 numpy/pandas 类型处理逻辑
orient 参数不是万能转换开关,它只控制顶层结构;内部值是否可序列化,得靠数据本身干净或额外清洗。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











