首页 / Pandas 入门教程 / 数据类型体系与转换

Pandas 入门教程

数据类型体系与转换

本教程共 54 篇 · 第 7 篇 · 更新于 2026-08-11 · 约 8 分钟阅读

PandasPandas 入门教程dtypeastypeNullable 类型类型转换

本节目标:看懂 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_dtypeis_string_dtype,写通用代码时很实用。按类型挑列用 select_dtypes,读到数据清洗章节会用到。

小结

三条之外还有一条心法:类型问题大多发生在读写边界(读文件、拼表、导出),在这些节点多检查 dtype,能省大量排查时间。

动手练一下:造一个 Series 混着整数和 None,先看它推断成什么类型,再分别用 astype(“Int64”)、astype(“str”) 转一遍,观察缺失值的变化。

记住三条:

  • 每列一个 dtype,类型由数据推断,不够装就自动升级
  • 转换用 astype,字符串类型判断用 “str”,可空整数用 “Int64”
  • 整数带缺失用 Int64,想要最合适的可空类型就用 convert_dtypes