在转换前,先查看当前数据的类型:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'ID': ['101', '102', '103'],
'年龄': ['28', '35', '42'],
'工资': ['8000', '12000', '15000'],
'入职日期': ['2020-01-15', '2018-06-01', '2015-11-23']
})
print(df.dtypes)
df.info()
你会发现所有列都是 object 类型,因为数据以字符串形式读入。
astype() 转换astype() 是最通用的类型转换方法,可以将 Series 或整个 DataFrame 转换为指定类型。
# 单列转换
df['ID'] = df['ID'].astype(int) # 转为整数
df['年龄'] = df['年龄'].astype(float) # 转为浮点数
df['入职日期'] = df['入职日期'].astype('datetime64[ns]') # 转为日期
# 多列转换(传入字典)
df = df.astype({'ID': int, '工资': float})
# 整个 DataFrame 转换(所有列转为同一类型)
df = df.astype(str) # 转为字符串
pd.to_numeric()当数据中包含无法直接转换的值(如空字符串、特殊字符)时,astype() 会报错。pd.to_numeric() 提供了更灵活的错误处理。
s = pd.Series(['1', '2', '3.5', 'NA', '5'])
# 默认遇到错误会抛出异常
# pd.to_numeric(s) # 报错
# 将无效值转为 NaN
s_num = pd.to_numeric(s, errors='coerce')
print(s_num)
# 忽略错误,保持原样(不推荐)
s_num2 = pd.to_numeric(s, errors='ignore') # 返回原 Series
# 对 DataFrame 的指定列应用
df['工资'] = pd.to_numeric(df['工资'], errors='coerce')
pd.to_datetime()将字符串或数字转换为 Pandas 的 datetime 类型,支持多种格式。
# 基本用法
df['入职日期'] = pd.to_datetime(df['入职日期'])
# 处理不同格式
s = pd.Series(['2024-01-01', '2024/02/01', '01-03-2024', 'invalid'])
dates = pd.to_datetime(s, errors='coerce') # 无效值转为 NaT
print(dates)
# 指定格式(提升速度,避免歧义)
df['日期'] = pd.to_datetime(df['日期'], format='%Y-%m-%d')
# 处理包含时间的字符串
df['时间戳'] = pd.to_datetime(df['时间戳'], format='%Y-%m-%d %H:%M:%S')
astype('category')对于重复值很多的离散列(如性别、地区),转换为 category 类型可以节省内存并提高性能。
df['部门'] = df['部门'].astype('category')
print(df['部门'].cat.categories) # 查看所有类别
print(df['部门'].cat.codes) # 查看编码后的整数
将数值或字符串转换为布尔值。
# 数值转布尔:0 -> False, 非0 -> True
df['是否活跃'] = df['状态'].astype(bool)
# 字符串转布尔(需自定义映射)
df['是否会员'] = df['会员'].map({'是': True, '否': False})
通过向下转换数据类型,可以大幅减少内存占用。
# 对于数值列,如果范围合适,可以转为更小的类型
df['年龄'] = pd.to_numeric(df['年龄']).astype('int8') # 如果年龄 < 127
df['工资'] = pd.to_numeric(df['工资']).astype('float32')
# Pandas 提供了自动向下转换函数
df_int = df.select_dtypes(include=['int']).apply(pd.to_numeric, downcast='unsigned')
df_float = df.select_dtypes(include=['float']).apply(pd.to_numeric, downcast='float')
import pandas as pd
import numpy as np
# 原始数据(模拟读取自 CSV)
df = pd.DataFrame({
'user_id': ['1001', '1002', '1003', '1004'],
'age': ['25', '30', 'NaN', '28'],
'salary': ['5000', '7500', '8200', 'N/A'],
'join_date': ['2023-01-15', '2022-06-01', '2023-11-20', '2021-03-10'],
'department': ['IT', 'HR', 'IT', 'Finance']
})
print("原始类型:")
print(df.dtypes)
# 1. 转换数值列,处理无效值
df['age'] = pd.to_numeric(df['age'], errors='coerce')
df['salary'] = pd.to_numeric(df['salary'], errors='coerce')
# 2. 转换日期列
df['join_date'] = pd.to_datetime(df['join_date'])
# 3. 将部门转为分类类型
df['department'] = df['department'].astype('category')
# 4. user_id 应作为字符串(而不是整数),因为可能包含前导0或非数字
df['user_id'] = df['user_id'].astype(str)
# 5. 内存优化:如果年龄范围小,可转为 int8
df['age'] = df['age'].fillna(0).astype('int8')
print("\n转换后类型:")
print(df.dtypes)
print("\n数据预览:")
print(df)
errors='coerce' 会导致无效值变为 NaN/NaT,后续需处理缺失值。
format 参数。
astype() 没有 inplace 参数,必须重新赋值。而 pd.to_numeric 返回新 Series。
dtypes,对每列规划合适的类型。pd.to_numeric 或 pd.to_datetime 配合 errors='coerce'。category 类型,可节省内存并加快 groupby 等操作。pd.to_numeric(downcast='integer/float') 或手动指定更小的 dtype。