现在位置: 首页 > Pandas 教程 > 正文

Pandas df.astype() 函数

Pandas 常用函数 Pandas 常用函数


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 类型(如 intstr)、NumPy 类型(如 np.int64np.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)

运行结果预期:

原始数据类型:
姓名     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

代码解析:

  1. 原始数据中,年龄和薪资都是字符串类型(object)。
  2. 使用 df['列名'].astype(int) 将字符串转换为整数。
  3. 转换后可以进行数值计算,如求和、平均值等。

示例 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)

运行结果预期:

原始数据类型:
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")

运行结果预期:

原始数据类型:
城市    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)

运行结果预期:

原始数据类型:
日期    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)

运行结果预期:

原始数据:
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       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 常用函数 Pandas 常用函数