自学教程 学编程从这里开始

Pandas 数据类型

Pandas 依托 NumPy,但扩展了一套自己的数据类型体系。很多莫名的 NaN、类型报错、内存占用高、分组异常、join对齐问题,根源都是数据类型。本文系统梳理原生numpy类型、Pandas扩展类型、分类类型、时间类型、字符串类型、类型转换、类型推断、类型检查、常见坑,延续整套教程风格。
前置导入

import pandas as pd
import numpy as np

一、核心概念

  • dtype:Series / DataFrame 每一列的数据类型
  • 旧版 Pandas 底层大量复用 NumPy 类型;Pandas 1.0+ 推出扩展数据类型(ExtensionDtype),专门解决 NumPy 原生类型不支持空值的痛点
  • 查看类型
df = pd.DataFrame({
    "商品": ["键盘","鼠标"],
    "数量": [2, 3],
    "金额": [178.0, 45.0]
})
df.dtypes
df["数量"].dtype
# 详细内存与类型诊断
df.info(memory_usage="deep")

区分:

  1. NumPy 原生类型:int64、float64、bool_、object
  2. Pandas 扩展类型:Int64、Float64、boolean、string、category、datetime64、timedelta64

二、NumPy 原生类型(传统)

1. int 整数

int8 / int16 / int32 / int64

  • 特点:不能存空值 NaN,一旦出现缺失,会自动向上转为 float
s = pd.Series([1, 2, None], dtype="int64")
print(s.dtype) # float64,自动上浮

2. float 浮点

float16 / float32 / float64

  • 可以表示 np.nan
  • 缺点:浮点数存在精度误差,金额、ID尽量避免float存储

3. bool 布尔

bool_

  • 只有 True / False;不支持空值,遇到None会变成object类型

4. object 对象类型(最容易踩坑)

dtype: object

  • 本质:一列存放Python对象(字符串、列表、字典、混合类型)
  • 弊端:
    • 内存占用大
    • str.xxx 向量化方法性能差
    • 分组、筛选速度慢
  • 常见场景:旧版本读取文本默认object;单元格内包含列表、字典

尽量优先使用 string 类型替代object存字符串。

5. datetime64 / timedelta64 时间类型

# datetime64[ns] 纳秒时间戳
s = pd.to_datetime(["2026-01-01", "2026-01-02"])
# timedelta64[ns] 时间间隔
s_delta = pd.to_timedelta(["1 day","2h"])
  • 支持 dt 访问器:year, month, day, weekday
  • 时间运算、resample、rolling时序统计必备

三、Pandas 扩展类型 ExtensionDtype(推荐新项目使用)

核心优势:原生支持 NA(pd.NA),不会因为空值强制上浮类型

类型写法说明
可空整数pd.Int64Dtype() / "Int64"大写I,支持pd.NA
可空浮点pd.Float64Dtype() / "Float64"大写F,支持pd.NA
可空布尔pd.BooleanDtype() / "boolean"支持pd.NA,三态:True/False/NA
字符串类型pd.StringDtype() / "string"专门存文本,替代object

示例:

# 可空整数,有空值也不会变成float
s_int = pd.Series([1, 2, None], dtype="Int64")
# 可空布尔
s_bool = pd.Series([True, False, None], dtype="boolean")
# 标准字符串类型
s_str = pd.Series(["键盘","鼠标", None], dtype="string")

注意大小写:int64(numpy,不可空) vs Int64(pandas扩展,可空)

四、Categorical 分类类型 category(高频优化类型)

适合重复值多、基数少的字段:渠道、商品、状态、省份、类别

s_cat = pd.Series(["线上","线下","线上"], dtype="category")

特点:

  1. 底层存储:唯一类别编码 + 映射表,内存大幅降低
  2. groupby、筛选、排序速度显著提升
  3. 支持自定义有序分类(图表、排序按指定顺序)
# 有序分类
s_cat = pd.Series(["低","中","高"], dtype=pd.CategoricalDtype(
    categories=["低","中","高"], ordered=True
))

常用属性:

s_cat.cat.categories   # 所有类别
s_cat.cat.codes        # 底层编码
s_cat.cat.ordered      # 是否有序

坑:category类型不能直接使用str访问器,需要先转string。

五、数据类型转换 astype / to_numeric

5.1 astype 强制转换

df["数量"] = df["数量"].astype("Int64")
df["商品"] = df["商品"].astype("string")
df["渠道"] = df["渠道"].astype("category")

astype 遇到无法转换的值直接报错。

5.2 pd.to_numeric 安全数值转换(清洗脏数据首选)

# errors="coerce" 无法转换的自动变成 NA
df["金额"] = pd.to_numeric(df["金额"], errors="coerce", downcast="float")
df["数量"] = pd.to_numeric(df["数量"], errors="coerce", downcast="integer")

downcast 自动向下压缩精度,节省内存。

5.3 pd.to_datetime 时间转换

df["date"] = pd.to_datetime(df["date"], errors="coerce")

六、读取文件时直接指定 dtype(性能最佳时机)

不要读完再转换,读取阶段就约束类型,减少内存占用

df = pd.read_csv(
    "sales.csv",
    dtype={
        "商品": "string",
        "渠道": "category",
        "数量": "Int64"
    },
    parse_dates=["下单日期"]
)

七、类型判断方法

s = df["金额"]
# 判断是否是数字
pd.api.types.is_numeric_dtype(s)
# 判断是否是字符串
pd.api.types.is_string_dtype(s)
# 判断是否是分类
pd.api.types.is_categorical_dtype(s)
# 判断是否是时间
pd.api.types.is_datetime64_any_dtype(s)
# 判断是否是可空布尔
pd.api.types.is_boolean_dtype(s)

八、类型自动推断 convert_dtypes(一键升级扩展类型)

Pandas 提供一键转换,自动把object转为string、int转为Int64等

df = df.convert_dtypes()

适合快速升级旧DataFrame,批量启用扩展可空类型。

九、类型对比总结表

需求推荐类型不推荐
带缺失的整数Int64int64
带缺失的布尔booleanbool_
文本字符串stringobject
重复多的类别字段categorystring / object
时间datetime64[ns]字符串
金额浮点Float64float64(注意精度)

十、高频坑清单

  1. int64 出现空值自动变成float64:整数丢失、精度异常,改用 Int64
  2. object类型存大量字符串:速度慢、内存大,改用 string
  3. category类型做str.extract、str.contains报错:先 .astype("string")
  4. 浮点数存订单号、ID:精度丢失,ID应该用 string
  5. 时间存字符串:无法dt访问、resample、窗口,必须转datetime64
  6. 混用 np.nan 和 pd.NA:扩展类型优先用 pd.NA
  7. astype 强转脏数据直接崩溃:脏数据清洗用 pd.to_numeric + errors=”coerce”
  8. 分类categories顺序不对,排序、图表顺序错乱:用 CategoricalDtype 指定有序列表

十一、综合实战模板

def cast_sales_dtype(df):
    df = df.copy()
    # 文本
    df["商品"] = df["商品"].astype("string")
    # 分类
    df["渠道"] = df["渠道"].astype("category")
    # 可空整数
    df["数量"] = pd.to_numeric(df["数量"], errors="coerce").astype("Int64")
    # 可空浮点
    df["金额"] = pd.to_numeric(df["金额"], errors="coerce").astype("Float64")
    # 时间
    df["下单日期"] = pd.to_datetime(df["下单日期"], errors="coerce")
    return df

十二、速查表

API作用
df.dtypes查看每列类型
astype()强制类型转换
pd.to_numeric清洗脏数据转为数值
pd.to_datetime转为时间
convert_dtypes()一键升级扩展类型
pd.CategoricalDtype自定义有序分类
pd.api.types.is_xxx_dtype类型判断
标签:

0 条笔记