数据类型体系与转换
本教程共 54 篇 · 第 7 篇 · 更新于 2026-08-11 · 约 8 分钟阅读
本节目标:看懂 dtype,认识 pandas 的常用数据类型,学会用 astype 转换,并掌握 Int64、boolean 等可空类型处理缺失值。
dtype 是什么
dtype(data type)是数据的类型。pandas 里「每列一个 dtype」:一列内类型必须统一,列与列之间可以不同。
import numpy as np
import pandas as pd
df = pd.DataFrame({
"整数": [1, 2, 3],
"浮点": [1.5, 2.5, 3.5],
"文字": ["a", "b", "c"],
"布尔": [True, False, True],
})
print(df.dtypes)
输出:
整数 int64
浮点 float64
文字 str
布尔 bool
dtype 决定了数据怎么存、怎么算:整数走 int64,文本走 str,日期走 datetime64。类型错了,运算结果也会错,比如「1」+「2」在字符串里是 “12”,在整数里是 3。所以看懂 dtype 是数据处理的基本功。
想知道每类列有几个,可以用 value_counts() 汇总:
import pandas as pd
df = pd.DataFrame({
"整数": [1, 2],
"浮点": [1.5, 2.5],
"文字": ["a", "b"],
"布尔": [True, False],
})
print(df.dtypes.value_counts())
常用 dtype 一览
NumPy 原生类型:
- int64、int32:整数
- float64、float32:浮点数
- bool:布尔
- datetime64:日期时间
- object:任意 Python 对象(3.0 之前字符串的默认归宿)
pandas 扩展类型(ExtensionDtype):
- str:3.0 起的新默认字符串类型
- category:分类类型,重复值多时省内存
- Int64、Float64:可空数值类型(注意大写 I)
- boolean:可空布尔(True/False/NA)
- datetime64[tz]:带时区的日期时间
还有两个偶尔见到的:timedelta64 表示时间差,complex 表示复数,用到时知道存在即可。
判断一列是不是数值类型,可以用 pd.api.types.is_numeric_dtype(df["整数"])。
默认情况下,整数固定是 int64、浮点固定是 float64,与操作系统是 32 位还是 64 位无关,行为可预期。
object 什么时候出现
object 是「万能口袋」,什么 Python 对象都能装。混装类型时就会落到它头上:
- 数值和字符串混在一列
- 一列里存列表、字典这类对象
- 老版本读进来的文本数据
3.0 之后纯文本列默认是 str,object 只剩真正的混合场景才出现。看到 object 列,通常值得检查一下数据是不是混了类型。
类型推断与自动升级
不指定 dtype 时,pandas 会根据数据推断,装不下时会自动升级:
import numpy as np
import pandas as pd
# 整数 + 浮点 -> 升为 float64
print(pd.Series([1, 2, 3.0]).dtype)
# 整数 + NaN -> 升为 float64(NaN 是浮点数,普通整数装不下)
print(pd.Series([1, 2, None]).dtype)
# 类型混杂 -> 变成 object
print(pd.Series([1, "a"]).dtype)
第三种情况在 3.0 里推断规则更聪明:纯文本列会得到 str,只有数值和字符串混在一起时才落到 object。
astype:显式转换
转换类型用 astype,返回新对象,不改原数据:
import pandas as pd
s = pd.Series(["1", "2", "3"])
# 字符串 -> 整数
print(s.astype("int64"))
# 浮点 -> 整数,小数部分直接丢弃
print(pd.Series([1.9, 2.1]).astype("int64"))
# 整数 -> 字符串
print(pd.Series([1, 2]).astype("str"))
# 数值 -> 布尔:0 变 False,非 0 变 True
print(pd.Series([0, 1, 2]).astype("bool"))
# 转分类类型
print(pd.Series(["低", "中", "高"]).astype("category"))
astype 不修改原对象,需要接住返回值;想链式转换也可以连着写:s.astype("str").astype("category")。
日期字符串转成真正的日期类型,后面做时间分析才有意义:
import pandas as pd
s = pd.Series(["2026-01-01", "2026-01-02"])
print(s.astype("datetime64[us]"))
转换失败会抛 ValueError,比如把字符串 “abc” 转整数。写转换前先用 dtype 看一眼数据,能少踩很多坑。
转换不成功时,先查有没有隐藏的缺失值或空格,比如字符串 ” 1” 带前导空格,转整数就会失败。
3.0 起
会保留缺失值:
pd.Series([1.5, np.nan]).astype("str")的结果里 NaN 还是 NaN。2.x 时代它会把 NaN 变成字符串 “nan”,很多老代码在这里踩过坑。想把所有值都变成字符串,用s.map(str)。
实际场景里的类型问题
读文件是类型问题的重灾区:CSV 里的数字可能被读成字符串,日期可能变成文本。处理套路是先看 df.dtypes 找到问题列,再用 astype 或 to_numeric、to_datetime 修回来(后面章节细讲)。
如果一列混了数字和文本,先想清楚为什么混:是数据质量问题,还是这一列本来就该是文本(比如邮编、电话号码)。强行转数值之前先观察。
老数据里常见的 object 文本列,想换成新字符串类型,转一次即可:
import pandas as pd
s = pd.Series(["a", "b"])
print(s.astype("str").dtype) # str
检查类型还有个快办法:df.dtypes.value_counts() 看整体分布,或者 df.select_dtypes(include=["str"]) 只挑文本列,后者第 17 章会用到。
Nullable 类型:整数也能有缺失值
前面看到:整数列一旦有 NaN 就被迫升级成 float64。对于 ID、评分这类「不该是浮点」的列,这很别扭。
pandas 提供可空类型解决这个问题,用 pd.NA 表示缺失:
import pandas as pd
# Int64(大写 I):整数 + 缺失值
s = pd.Series([1, 2, None], dtype="Int64")
print(s) # 缺失显示 <NA>
可空类型参与运算时,缺失值会照常传播,聚合时自动跳过:
import pandas as pd
s = pd.Series([1, 2, None], dtype="Int64")
print(s + 1) # 缺失保持 <NA>
print(s.sum()) # 3,自动跳过缺失
pandas 里缺失值有好几种写法(None、np.nan、pd.NA),各自的语义和区别在 §24 详讲。日常判断缺失统一用 isna(),不用纠结具体是哪个。
注意大小写:Int64(大写 I)是 pandas 可空整数,int64(小写)是 NumPy 普通整数。写错会得到不符合预期的类型。
自动推断:convert_dtypes
手写 dtype 太麻烦?convert_dtypes 可以一键把整张表转成「最合适的可空类型」:
import pandas as pd
df = pd.DataFrame({
"整数": [1, None],
"浮点": [1.5, None],
"布尔": [True, None],
"文字": ["a", None],
})
print(df.convert_dtypes().dtypes)
输出:
整数 Int64
浮点 Float64
布尔 boolean
文字 string
注意文字列得到的是 string(可空字符串类型,缺失用 pd.NA),和 3.0 默认的 str(缺失用 NaN)略有区别,日常使用差别不大。
读 CSV 之后对整表跑一次 convert_dtypes,是处理缺失数据的常见起手式。
小提示:convert_dtypes 返回新表,记得接住返回值,比如 df = df.convert_dtypes()。
convert_dtypes 也能单独用于一列:df["整数"].convert_dtypes()。
类型选择建议
日常写代码可以这样选:
- 纯整数、无缺失:int64
- 整数、可能有缺失:Int64
- 金额、测量值:float64 或 Float64
- 文本:str(3.0 默认)
- 只有两类值的标记列:bool 或 boolean
bool 和 boolean 的差别:bool 是 NumPy 原生类型,装不下缺失值;boolean 是可空版,支持 True/False/NA 三态。判断「某列是否存在缺失」这类场景,后者更稳。
拿不准时用 convert_dtypes 让 pandas 替你选,再看输出确认是否符合预期。类型选择没有绝对标准,以「运算结果正确加内存合理」为目标即可。
判断类型的辅助函数在
下,比如
is_numeric_dtype、is_string_dtype,写通用代码时很实用。按类型挑列用select_dtypes,读到数据清洗章节会用到。
小结
三条之外还有一条心法:类型问题大多发生在读写边界(读文件、拼表、导出),在这些节点多检查 dtype,能省大量排查时间。
动手练一下:造一个 Series 混着整数和 None,先看它推断成什么类型,再分别用 astype(“Int64”)、astype(“str”) 转一遍,观察缺失值的变化。
记住三条:
- 每列一个 dtype,类型由数据推断,不够装就自动升级
- 转换用 astype,字符串类型判断用 “str”,可空整数用 “Int64”
- 整数带缺失用 Int64,想要最合适的可空类型就用 convert_dtypes