Pandas df.astype() 函数
df.astype() 是 Pandas 中用于转换 DataFrame 或 Series 数据类型的函数。
在数据处理过程中,数据类型不匹配是常见的问题。例如,数字存储为字符串、日期存储为文本等。astype() 允许你显式地将数据转换为所需的类型,如整数、浮点数、字符串、日期等,确保数据能够进行正确的计算和分析。
基本语法与参数
astype() 既是 DataFrame 的成员函数,也是 Series 的成员函数,通过点运算符 . 来调用。
语法格式
DataFrame.astype(dtype, copy=True, errors='raise') Series.astype(dtype, copy=True, errors='raise')
参数说明
| 参数 | 类型 | 是否必填 | 说明 | 默认值 |
|---|---|---|---|---|
| dtype | Python dtype 或 numpy dtype | 必填 | 目标数据类型。可以是 Python 类型(如 int、str)、NumPy 类型(如 np.int64、np.float32)或 Pandas 类型(如 'int64'、'float64'、'category')。 |
无 |
| copy | bool | 可选 | 如果为 True,总是返回一个新的对象;如果为 False,在可能的情况下在原对象上修改。 |
True |
| errors | str | 可选 | 控制错误处理。'raise' 表示转换失败时抛出异常;'ignore' 表示转换失败时返回原始数据,不抛出异常。 |
'raise' |
返回值说明
- 返回一个新的 DataFrame 或 Series,其中所有指定列的数据类型已转换为目标类型。
实例
让我们通过一系列例子,彻底掌握 astype() 的用法。
示例 1:转换单列的数据类型
将 Series 或 DataFrame 的某一列转换为指定类型。
实例
import pandas as pd
# 创建一个 DataFrame,数值被存储为字符串
data = {
'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': ['25', '30', '35', '28'], # 存储为字符串
'薪资': ['5000', '6000', '5500', '7000'] # 存储为字符串
}
df = pd.DataFrame(data)
print("原始数据类型:")
print(df.dtypes)
print("=" * 50)
# 将"年龄"列转换为整数类型
df['年龄'] = df['年龄'].astype(int)
print("转换年龄列后的数据类型:")
print(df.dtypes)
print("=" * 50)
# 将"薪资"列转换为浮点数类型
df['薪资'] = df['薪资'].astype(float)
print("转换薪资列后的数据类型:")
print(df.dtypes)
print("=" * 50)
print("转换后的数据:")
print(df)
# 创建一个 DataFrame,数值被存储为字符串
data = {
'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': ['25', '30', '35', '28'], # 存储为字符串
'薪资': ['5000', '6000', '5500', '7000'] # 存储为字符串
}
df = pd.DataFrame(data)
print("原始数据类型:")
print(df.dtypes)
print("=" * 50)
# 将"年龄"列转换为整数类型
df['年龄'] = df['年龄'].astype(int)
print("转换年龄列后的数据类型:")
print(df.dtypes)
print("=" * 50)
# 将"薪资"列转换为浮点数类型
df['薪资'] = df['薪资'].astype(float)
print("转换薪资列后的数据类型:")
print(df.dtypes)
print("=" * 50)
print("转换后的数据:")
print(df)
运行结果预期:
原始数据类型:
姓名 object
年龄 object # 字符串类型
薪资 object # 字符串类型
==================================================
转换年龄列后的数据类型:
姓名 object
年龄 int64 # 整数类型
薪资 object
==================================================
转换薪资列后的数据类型:
姓名 object
年龄 int64
薪资 float64 # 浮点数类型
==================================================
转换后的数据:
姓名 年龄 薪资
0 张三 25 5000.0
1 李四 30 6000.0
2 王五 35 5500.0
3 赵六 28 7000.0
代码解析:
- 原始数据中,年龄和薪资都是字符串类型(
object)。 - 使用
df['列名'].astype(int)将字符串转换为整数。 - 转换后可以进行数值计算,如求和、平均值等。
示例 2:转换整个 DataFrame 的数据类型
可以一次性为整个 DataFrame 指定数据类型。
实例
import pandas as pd
# 创建一个 DataFrame
data = {
'A': [1, 2, 3, 4],
'B': [1.5, 2.5, 3.5, 4.5],
'C': ['a', 'b', 'c', 'd']
}
df = pd.DataFrame(data)
print("原始数据类型:")
print(df.dtypes)
print("=" * 50)
# 将 A 列转换为 float64,B 列转换为 int64
df_converted = df.astype({'A': 'float64', 'B': 'int64'})
print("转换后的数据类型:")
print(df_converted.dtypes)
print("=" * 50)
print("转换后的数据:")
print(df_converted)
# 创建一个 DataFrame
data = {
'A': [1, 2, 3, 4],
'B': [1.5, 2.5, 3.5, 4.5],
'C': ['a', 'b', 'c', 'd']
}
df = pd.DataFrame(data)
print("原始数据类型:")
print(df.dtypes)
print("=" * 50)
# 将 A 列转换为 float64,B 列转换为 int64
df_converted = df.astype({'A': 'float64', 'B': 'int64'})
print("转换后的数据类型:")
print(df_converted.dtypes)
print("=" * 50)
print("转换后的数据:")
print(df_converted)
运行结果预期:
原始数据类型:
A int64
B float64
C object
==================================================
转换后的数据类型:
A float64
B int64 # 小数部分被截断
C object
==================================================
转换后的数据:
A B C
0 1.0 2 a
1 2.0 2 b
2 3.0 3 c
3 4.0 4 d
代码解析:
- 使用字典
{'列名': '类型'}可以一次性指定多列的转换类型。 - 将 B 列的浮点数转换为整数时,小数部分会被截断(2.5 变成 2)。
示例 3:转换为分类数据类型
分类数据类型(category)可以节省内存,特别适合取值有限的列。
实例
import pandas as pd
# 创建一个包含大量重复值的 DataFrame
data = {
'城市': ['北京', '上海', '广州', '深圳', '北京', '上海', '广州', '深圳'] * 1000,
'编号': range(8000)
}
df = pd.DataFrame(data)
print("原始数据类型:")
print(df.dtypes)
print(f"内存使用: {df.memory_usage(deep=True).sum() / 1024:.2f} KB")
print("=" * 50)
# 将"城市"列转换为分类类型
df['城市'] = df['城市'].astype('category')
print("转换后的数据类型:")
print(df.dtypes)
print(f"内存使用: {df.memory_usage(deep=True).sum() / 1024:.2f} KB")
# 创建一个包含大量重复值的 DataFrame
data = {
'城市': ['北京', '上海', '广州', '深圳', '北京', '上海', '广州', '深圳'] * 1000,
'编号': range(8000)
}
df = pd.DataFrame(data)
print("原始数据类型:")
print(df.dtypes)
print(f"内存使用: {df.memory_usage(deep=True).sum() / 1024:.2f} KB")
print("=" * 50)
# 将"城市"列转换为分类类型
df['城市'] = df['城市'].astype('category')
print("转换后的数据类型:")
print(df.dtypes)
print(f"内存使用: {df.memory_usage(deep=True).sum() / 1024:.2f} KB")
运行结果预期:
原始数据类型: 城市 object 编号 int64 内存使用: ~456 KB ================================================== 转换后的数据类型: 城市 category 编号 int64 内存使用: ~120 KB # 内存使用大幅减少
代码解析:
- 分类数据类型会为每个唯一值分配一个整数标识,比存储完整字符串节省大量内存。
- 原始数据 8000 行,内存使用约 456 KB,转换后约 120 KB,节省了约 75% 的内存。
- 这种方法特别适合取值较少的分类变量。
示例 4:转换日期时间类型
将字符串转换为日期时间类型,以便进行日期相关的操作。
实例
import pandas as pd
# 创建一个包含日期字符串的 DataFrame
data = {
'日期': ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04'],
'销量': [100, 150, 120, 180]
}
df = pd.DataFrame(data)
print("原始数据类型:")
print(df.dtypes)
print("=" * 50)
# 将"日期"列转换为日期时间类型
df['日期'] = pd.to_datetime(df['日期'])
print("转换后的数据类型:")
print(df.dtypes)
print("=" * 50)
print("转换后的数据:")
print(df)
# 现在可以进行日期相关的操作
print("n提取月份:")
print(df['日期'].dt.month)
# 创建一个包含日期字符串的 DataFrame
data = {
'日期': ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04'],
'销量': [100, 150, 120, 180]
}
df = pd.DataFrame(data)
print("原始数据类型:")
print(df.dtypes)
print("=" * 50)
# 将"日期"列转换为日期时间类型
df['日期'] = pd.to_datetime(df['日期'])
print("转换后的数据类型:")
print(df.dtypes)
print("=" * 50)
print("转换后的数据:")
print(df)
# 现在可以进行日期相关的操作
print("n提取月份:")
print(df['日期'].dt.month)
运行结果预期:
原始数据类型:
日期 object # 字符串类型
销量 int64
==================================================
转换后的数据类型:
日期 datetime64[ns] # 日期时间类型
销量 int64
==================================================
转换后的数据:
日期 销量
0 2024-01-01 100
1 2024-01-02 150
2 2024-01-03 120
3 2024-01-04 180
提取月份:
0 1
1 1
2 1
3 1
Name: 日期, dtype: int64
代码解析:
- 使用
pd.to_datetime()将字符串转换为日期时间类型。 - 转换后可以使用
.dt访问器进行日期操作,如提取月份、星期几等。 - 注意:虽然也可以用
astype('datetime64[ns]'),但pd.to_datetime()更加强大和灵活。
示例 5:处理转换错误
使用 errors='ignore' 参数可以处理转换失败的情况。
实例
import pandas as pd
# 创建一个包含无法转换为整数的值的 Series
s = pd.Series(['1', '2', 'hello', '4', 'world'])
print("原始数据:")
print(s)
print("=" * 50)
# 尝试转换,使用 errors='raise'(默认)会抛出异常
try:
s_converted = s.astype(int)
except ValueError as e:
print(f"转换失败: {e}")
print("=" * 50)
# 使用 errors='ignore',转换失败时返回原始数据
s_converted = s.astype(int, errors='ignore')
print("使用 errors='ignore' 转换后的数据:")
print(s_converted)
print("=" * 50)
# 使用 errors='coerce',转换失败时用 NaN 填充
s_converted2 = s.astype(float, errors='coerce')
print("使用 errors='coerce' 转换后的数据:")
print(s_converted2)
# 创建一个包含无法转换为整数的值的 Series
s = pd.Series(['1', '2', 'hello', '4', 'world'])
print("原始数据:")
print(s)
print("=" * 50)
# 尝试转换,使用 errors='raise'(默认)会抛出异常
try:
s_converted = s.astype(int)
except ValueError as e:
print(f"转换失败: {e}")
print("=" * 50)
# 使用 errors='ignore',转换失败时返回原始数据
s_converted = s.astype(int, errors='ignore')
print("使用 errors='ignore' 转换后的数据:")
print(s_converted)
print("=" * 50)
# 使用 errors='coerce',转换失败时用 NaN 填充
s_converted2 = s.astype(float, errors='coerce')
print("使用 errors='coerce' 转换后的数据:")
print(s_converted2)
运行结果预期:
原始数据: 0 1 1 2 2 hello # 无法转换为整数 3 4 4 world # 无法转换为整数 ================================================== 转换失败: invalid literal for int() with base 10: 'hello' ================================================== 使用 errors='ignore' 转换后的数据: 0 1 1 2 2 hello # 保持原值 3 4 4 world # 保持原值 ================================================== 使用 errors='coerce' 转换后的数据: 0 1.0 1 2.0 2 NaN # 无法转换,设为 NaN 3 4.0 4 NaN # 无法转换,设为 NaN
代码解析:
- 当字符串包含无法转换为数字的值时,默认会抛出
ValueError异常。 errors='ignore'会保持原始数据不变。errors='coerce'会将无法转换的值设为NaN,这是处理脏数据的常用方法。
示例 6:转换为布尔类型
将数据转换为布尔类型,常用于条件筛选和逻辑运算。
实例
import pandas as pd
# 创建一个包含 0 和 1 的 DataFrame
data = {
'是否会员': [0, 1, 1, 0, 1],
'是否激活': ['是', '否', '是', '是', '否']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("原始数据类型:")
print(df.dtypes)
print("=" * 50)
# 将 0/1 转换为布尔类型
df['是否会员'] = df['是否会员'].astype(bool)
print("转换是否会员列后的数据类型:")
print(df.dtypes)
print(df)
print("=" * 50)
# 将"是"/"否"转换为布尔类型
df['是否激活'] = df['是否激活'].map({'是': True, '否': False})
print("转换是否激活列后的数据:")
print(df)
print(df.dtypes)
# 创建一个包含 0 和 1 的 DataFrame
data = {
'是否会员': [0, 1, 1, 0, 1],
'是否激活': ['是', '否', '是', '是', '否']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("原始数据类型:")
print(df.dtypes)
print("=" * 50)
# 将 0/1 转换为布尔类型
df['是否会员'] = df['是否会员'].astype(bool)
print("转换是否会员列后的数据类型:")
print(df.dtypes)
print(df)
print("=" * 50)
# 将"是"/"否"转换为布尔类型
df['是否激活'] = df['是否激活'].map({'是': True, '否': False})
print("转换是否激活列后的数据:")
print(df)
print(df.dtypes)
运行结果预期:
原始数据: 是否会员 是否激活 0 0 是 1 1 否 2 1 是 3 0 是 4 1 否 ================================================== 转换是否会员列后的数据类型: 是否会员 bool 是否激活 object ================================================== 转换是否激活列后的数据: 是否会员 是否激活 0 True True 1 True False 2 True True 3 False True 4 True False
代码解析:
- 0 可以转换为
False,1 转换为True。 - 对于"是"/"否"这类字符串,需要使用
map()来转换。 - 转换后可以使用布尔索引进行快速筛选。
注意事项
astype()默认返回一个新的对象,不会修改原始数据。如果想原地修改,可以使用copy=False参数,但可能会影响原始数据。- 将浮点数转换为整数时,小数部分会被截断,不会四舍五入。
- 将字符串转换为数字时,确保字符串是有效的数字格式,否则会抛出异常。
- 使用
errors='coerce'是处理脏数据的推荐方法,可以将无效值转换为NaN,然后使用fillna()进行填充。 - 对于大量重复值的列,转换为分类类型可以显著减少内存使用。

Pandas 常用函数