4.4 数据类型转换

本章学习目标

  • 理解数据类型错误会导致哪些分析错误
  • 掌握最常见的类型问题:数字存成文本、日期存成文本
  • 学会用info()快速发现类型问题
  • 知道每类问题应该如何转换、转换成什么
  • 不需要记住代码,只需要知道"有什么问题、转成什么、怎么告诉AI"

一、为什么数据类型转换如此重要?

1.1 核心认知:类型决定操作

数据类型决定了你能做什么操作,也决定了不能做什么操作。

你想做的事 数字类型(int/float) 文本类型(object/string) 日期类型(datetime)
计算平均值 ✅ 可以 ❌ 不行(会报错或得到无意义结果) ❌ 不行
比较大小 ✅ 可以 ❌ 不行(按字典序,结果怪异) ✅ 可以
加减运算 ✅ 可以 ❌ 不行 ✅ 可以(算天数差)
提取年月日 ❌ 不行 ❌ 不行 ✅ 可以
判断是否相等 ✅ 可以 ✅ 可以 ✅ 可以
分组统计 ✅ 可以 ✅ 可以 ✅ 可以

1.2 类型错误的后果

错误类型 现象 严重后果
数字存成文本 无法求和、求平均 统计数字全是错的
数字存成文本 排序结果异常("10"排在"2"前面) 排名错误
日期存成文本 无法计算时间差 无法计算用户生命周期
日期存成文本 无法按年月聚合 时间趋势分析做不了
ID存成数字 不知不觉对ID求了平均 得到完全无意义的结果
分类存成数字 模型误认为有大小顺序 模型效果变差

1.3 一个真实的教训

场景:某公司分析用户年龄分布

数据:年龄列看起来是数字,但实际是文本类型

错误的操作

python 复制代码
# 用户以为年龄是数字,直接求平均
df['age'].mean()
# 报错!因为文本类型不能求平均

即使没报错,也可能是错的

python 复制代码
# 如果年龄列混入了"Unknown"、"30岁"等文本
# mean() 会报错,但 sum() 可能不会报错却给出错误结果

核心原则:类型对了,分析才可能对;类型错了,结果一定是错的。


二、常见类型问题与场景

2.1 问题类型总览

问题类型 当前类型 应有的类型 典型场景
数字存成文本 object/string int/float 从Excel导入时,数字被当作文本
日期存成文本 object/string datetime 从CSV导入时,日期被读成普通文本
ID存成数字 int64 string 用户ID、订单号不应参与数学运算
分类存成数字 int64 category 性别编码为1/2,但不应有大小关系
文本应该拆分 object 多列 姓名"张三"应该拆成姓"张"名"三"
数字精度错误 int64 float 价格需要小数却存成了整数

2.2 为什么会出现类型问题?

原因 举例 说明
CSV或Excel导入时未指定类型 手机号18812345678被读成整数1.88e10 需要提前告诉工具"这是文本"
数据中包含非数字字符 "30岁"、"$100" 混入了文字或符号
日期格式不标准 2024年1月15日 vs 2024-01-15 不同格式识别率不同
空值或占位符 用"-"或"N/A"表示缺失 导致整列变成文本
前导零问题 "00123"变成了123 Excel自动去掉了前导零

2.3 具体例子对比

正常情况(类型正确)

user_id (数字) name (文本) age (数字) salary (数字) join_date (日期)
101 张三 28 8000.5 2024-01-15

有问题的情况

user_id (数字) name (文本) age (文本) salary (文本) join_date (文本)
101 张三 28岁 8,000.5 2024年1月15日

问题分析

  • age:文本类型,且包含"岁"字 → 无法计算平均年龄
  • salary:文本类型,且包含逗号 → 无法求和
  • join_date:文本类型,格式不标准 → 无法计算工龄

三、怎么发现类型问题?

3.1 主力工具:info()

info() 是最快发现类型问题的工具。它一次性显示所有列的类型。

输出示例

复制代码
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 6 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   user_id   1000 non-null   int64  
 1   name      1000 non-null   object 
 2   age       1000 non-null   object   ← 问题1:年龄应该是数字,却是object
 3   salary    998 non-null    object   ← 问题2:薪资应该是数字,却是object
 4   join_date 1000 non-null   object   ← 问题3:日期应该是datetime,却是object
 5   is_vip    1000 non-null   int64   

一眼看出问题

  • ageobject(文本)→ 应该是 intfloat
  • salaryobject(文本)→ 应该是 float
  • join_dateobject(文本)→ 应该是 datetime

3.2 辅助方法:查看唯一值

info()显示类型异常时,用unique()head()查看具体内容,确认问题原因。

查看年龄列的唯一值

python 复制代码
df['age'].unique()
# 输出:['28', '30', '25岁', 'unknown', '29']

→ 发现问题:有"25岁"(带单位)、"unknown"(文本)混入,导致整列变文本

查看薪资列的前几行

python 复制代码
df['salary'].head()
# 输出:['8,000', '10,500', '7,000', '12,000', '9,500']

→ 发现问题:数字中带了逗号分隔符

查看日期列的前几行

python 复制代码
df['join_date'].head()
# 输出:['2024年1月15日', '2023-05-20', '2024/03/10', '2022.12.01', '2024-01-01']

→ 发现问题:日期格式不统一

3.3 业务直觉

有时候,info()不报错,但业务逻辑告诉你类型不对:

情况 info显示 业务直觉 应该做什么
用户ID是int64 数字类型 "用户ID不应该用来求平均" 转为文本
性别编码是int64 数字类型 "1和2没有大小的意义" 转为分类
评分是object 文本类型 "评分应该是1-5的数字" 清理后转数字

3.4 发现问题的检查清单

检查项 问自己 异常信号
ID列 这个ID有算术意义吗? 没有 → 应该转文本
数字列 类型是int或float吗? 是object → 需要转换
日期列 类型是datetime吗? 是object → 需要转换
分类列 类型是category吗? 是int且取值少 → 可能需要转分类
金额列 需要小数吗? 是int → 可能需要转float

四、类型转换对照表

4.1 目标类型与用途

目标类型 中文名 用途 典型列
int 整数 计数、整数运算 年龄、数量
float 浮点数 带小数的数值运算 价格、百分比
str / object 文本 比较、匹配、拆分 姓名、地址
datetime 日期时间 时间差、提取年月 注册日期、订单时间
category 分类 节省内存、分组聚合 性别、省份、状态

4.2 常见转换对照表

当前状态 表现 应转为 处理方式
数字文本 "123" int/float 直接转换
带单位的数字 "25岁""$100" int/float 先提取数字,再转换
带千位分隔符的数字 "10,000" int/float 先去掉逗号,再转换
带空格的文本 "北京 " str 去除空格
标准日期文本 "2024-01-15" datetime 直接转换
非标准日期文本 "2024年1月15日" datetime 指定格式转换
纯数字日期 20240115 datetime 先转文本,再按格式转日期
文本型ID "00123"(显示为123) str 读取时指定为文本,或填充前导零

五、各类问题的解决方案

5.1 问题一:数字存成了文本

如何发现

  • info() 显示类型为 object
  • 但实际内容应该能进行数学运算

常见原因与解决

原因 例子 怎么告诉AI
完全干净的数字文本 "123" "把年龄列从文本转成整数"
包含空格 " 123 " "先把年龄列去除空格,再转成整数"
包含单位 "25岁" "从年龄列中提取数字部分,再转成整数"
包含千位分隔符 "10,000" "去掉薪资列的逗号,再转成浮点数"
混合了文本占位符 "unknown""-" "把年龄列中的unknown替换成空,再转成数字"

5.2 问题二:日期存成了文本

如何发现

  • info() 显示类型为 object
  • 列名包含 datetime日期注册订单 等关键词

常见原因与解决

原因 例子 怎么告诉AI
标准格式 "2024-01-15" "把订单日期列转成日期格式"
斜杠分隔 "2024/01/15" "把日期列从文本转成日期格式,原格式是年/月/日"
中文格式 "2024年1月15日" "把中文日期列转成标准日期格式"
纯数字 20240115 "把注册日期列从整数转成日期格式,原格式是YYYYMMDD"
月日年 "01/15/2024" "把日期列转成日期格式,原格式是月/日/年"
带时间 "2024-01-15 14:30:00" "把订单时间列转成日期时间格式"

5.3 问题三:ID存成了数字

为什么这是问题

  • 用户ID 00123 被读成 123,丢失了前导零
  • 你不小心对ID列求了平均,得到了一个无意义的数字

如何发现

  • 列名包含 idcode编号用户 等关键词
  • info() 显示为 int64

解决方法

场景 怎么告诉AI
读取时就指定类型 "读取CSV时,把用户ID列当成字符串读"
已经读成了数字 "把用户ID列从整数转成字符串,注意要补全前导零到5位"

5.4 问题四:分类存成了数字

为什么这是问题

  • 某些模型(如线性回归)会误认为 1 < 2 < 3 有意义
  • 但实际上"华为"、"小米"、"苹果"的大小顺序毫无意义

如何发现

  • 列取值是有限的几个数字(如 1,2,3
  • 但业务含义是分类(品牌、车型、颜色)

解决方法

场景 怎么告诉AI
转换为分类类型(节省内存) "把品牌编码列转成category类型"
保留数字但告知业务含义 建模时独热编码,保持分类含义
映射为有意义的标签 "把性别列:1映射为男性、2映射为女性"

5.5 问题五:文本应该拆分(组合型数据)

为什么这是问题

  • 一列里包含了多个信息,无法直接分析

例子

当前列 应拆分为
"张三,28,北京" 姓名、年龄、城市
"192.168.1.1" 四段独立IP可能无用,但有时需拆分

解决方法

场景 怎么告诉AI
按分隔符拆分 "把姓名和年龄列按逗号拆分成两列"
提取部分信息 "从身份证号列中提取出生年月日"
拆分同时保留原列 "拆分地址列为省、市、区三列,保留原地址列"

5.6 问题六:数字精度错误

为什么这是问题

  • 价格需要小数(199.99)却存成了整数(199) → 丢失精度

如何发现

  • 列名包含 priceamountratio 等关键词
  • info() 显示为 int64

解决方法

场景 怎么告诉AI
整数转浮点 "把价格列从整数转成浮点数"
进位处理 "把价格列从整数转成浮点数,除以100得到真实价格"

六、类型转换的注意事项

6.1 转换可能失败

当列中包含无法转换的值时,转换会报错。

问题 例子 解决方案
包含非数字字符 "25岁" 先清理,再转换
包含空值/占位符 "-""unknown" 先处理缺失值,再转换
混合格式 "2024-01-15""2024年1月15日" 先统一格式,再转换

告诉AI的方式

"把年龄列转成数字时,遇到无法转换的设为空值,然后告诉我哪些行有问题"

6.2 转换顺序很重要

对于复杂情况,可能需要多步处理:

复制代码
原始数据:"25岁"
    ↓ 第一步:提取数字 → "25"
    ↓ 第二步:转成整数 → 25
    ↓ 第三步:确认类型 → int64

告诉AI的方式

"从年龄列中提取数字部分,然后转成整数类型"

6.3 原始数据最好保留

在清洗过程中,建议保留原始列,创建新列存放转换后的数据。

原因

  • 万一转换逻辑错了,可以重新来过
  • 可以对比原始和转换后的结果,验证正确性

告诉AI的方式

"创建一个新列'age_clean',从'age'列提取数字作为新列的值"


七、实战案例:二手车数据集类型转换

7.1 发现类型问题

使用info()检查

复制代码
Data columns (total 30 columns):
 #   Column             Non-Null Count  Dtype  
---  ------             --------------  -----  
 0   SaleID             150000 non-null  int64  
 1   name               150000 non-null  int64  
 2   regDate            150000 non-null  int64     ← 应该是日期
 3   model              149999 non-null  float64 
 4   brand              150000 non-null  int64  
 5   bodyType           145000 non-null  float64 
 6   fuelType           141000 non-null  float64 
 7   gearbox            144000 non-null  float64 
 8   power              150000 non-null  int64  
 9   kilometer          150000 non-null  float64 
 10  notRepairedDamage  120000 non-null  object    ← 应该是0/1
 11  regionCode         150000 non-null  int64  
 12  seller             150000 non-null  int64  
 13  offerType          150000 non-null  int64  
 14  creatDate          150000 non-null  int64     ← 应该是日期
 15  price              150000 non-null  int64
 ...

发现的问题

列名 当前类型 应有类型 优先级
regDate int64 datetime
creatDate int64 datetime
notRepairedDamage object int/float
SaleID int64 string 低(但转更好)

7.2 处理决策

列名 处理方式 怎么告诉AI
regDate 整数 → 日期 "把regDate从整数转成日期格式,原格式是YYYYMMDD"
creatDate 整数 → 日期 "把creatDate从整数转成日期格式,原格式是YYYYMMDD"
notRepairedDamage 清理 → 数字 "把notRepairedDamage列中的'-'替换为空,然后转成数字类型"
SaleID 整数 → 文本 "把SaleID转成字符串类型"

7.3 转换后的验证

告诉AI验证

"转换完成后,再用info确认一下类型是否正确"

预期结果

  • regDatecreatDate 显示为 datetime64
  • notRepairedDamage 显示为 float64
  • SaleID 显示为 objectstring

八、如何向AI描述类型转换需求

8.1 基础转换

你的需求 你应该这样告诉AI
查看所有类型 "用info查看每列的数据类型"
文本转数字 "把年龄列从文本转成整数"
文本转小数 "把价格列从文本转成浮点数"
文本转日期 "把订单日期列转成日期格式"
数字转文本 "把用户ID列从整数转成字符串"
数字转分类 "把性别编码列转成category类型"

8.2 有问题的转换

你的需求 你应该这样告诉AI
带单位 "从年龄列中提取数字部分,再转成整数"
带千位分隔符 "去掉薪资列的逗号,再转成浮点数"
千位分隔符+小数点 "把金额列中的逗号去掉,然后转成浮点数"
中文日期 "把注册日期从'2024年1月15日'格式转成标准日期"
纯数字日期 "把regDate从整数转成日期,格式是YYYYMMDD"
混合格式 "尝试把日期列转成日期格式,无法解析的设为空"
处理占位符 "把年龄列中的unknown替换为空,然后转成数字"

8.3 验证与调试

你的需求 你应该这样告诉AI
验证转换结果 "转换完成后,用info确认类型是否正确"
找出转换失败的行 "年龄列转数字时,哪些行转换失败了?显示出来"
安全转换(不报错) "把年龄列转成数字,遇到错误就设为空值"

九、本章总结

核心知识点回顾

  1. 为什么重要:类型决定操作,类型错了分析全错
  2. 怎么发现info() 是主力工具,业务直觉辅助
  3. 常见问题
    • 数字存成文本 → 转数字
    • 日期存成文本 → 转日期
    • ID存成数字 → 转文本
    • 分类存成数字 → 转分类
  4. 怎么转换:告诉AI"把X列从A类型转成B类型"

快速诊断卡

观察 判断 怎么告诉AI
info()显示数字列为object 数字存成了文本 "把XX列转成数字"
info()显示日期列为object 日期存成了文本 "把XX列转成日期"
列名含id,类型是数字 ID不该是数字 "把XX列转成字符串"
列名含price,类型是整数 价格需要小数 "把XX列转成浮点数"

核心心法

"类型对了,分析才可能对。拿到数据的第一件事:用info()扫一眼类型,感觉不对就转。"


十、思考题

  1. 你用info()发现age列是object类型,且包含"25岁""30""unknown"三种内容。你会怎么处理?分几步?

  2. 日期列存成了整数20240115格式。你想转成真正的日期。你会怎么告诉AI?

  3. 交易金额列amount显示为object,前几行是"1,200.50""2,000.00""500"。这是什么问题?怎么处理?

  4. 用户ID列user_id在Excel里是00123,读进Python后变成了123。为什么?怎么解决?

  5. 一个"用户评分"列,理论上应该是1-5的数字。info()显示是int64,看起来没问题。但你发现用户对评分的排序不对:"10"排在了"2"前面。问题出在哪里?


相关推荐
程序员猫哥_2 小时前
零基础极速上手:用AI建站工具10分钟搭建一个专业网站
数据挖掘
消失在人海中2 小时前
使用Pytho做数据分析
数据挖掘·数据分析
数据科学小丫2 小时前
PowerBI 可视化操作——常用视觉对象(堆积条形图、折线图、堆积柱形图、着色地图、丝带图、分解树、瀑布图、散点图...共计 16 种视觉对象)
数据分析·数据可视化·powerbi
70asunflower3 小时前
3.4 数据分析实战:体检报告
数据挖掘·数据分析
70asunflower3 小时前
数据分析实战教程:从思维到落地
数据挖掘·数据分析
babe小鑫3 小时前
财务经理学数据分析可行性分析
信息可视化·数据挖掘·数据分析
babe小鑫3 小时前
2026市场投放学数据分析的价值分析
数据挖掘·数据分析
clarance20153 小时前
基于NLP的BI工具DataFocus实战:从自然语言查询到智能数据分析
人工智能·经验分享·自然语言处理·数据分析
源码之家4 小时前
计算机毕业设计:Python基于知识图谱与深度学习的医疗智能问答系统 Django框架 Bert模型 深度学习 知识图谱 大模型(建议收藏)✅
python·深度学习·机器学习·数据分析·flask·知识图谱·课程设计