当前位置: 代码网 > it编程>前端脚本>Python > 在pandas中更改列类型方式

在pandas中更改列类型方式

2025年10月24日 Python 我要评论
在 pandas 中有四个主要选项来转换类型:to_numeric() - 提供功能以安全地将非数值类型(例如字符串)转换为合适的数值类型。(另见 to_datetime() 和 to_timedel

在 pandas 中有四个主要选项来转换类型:

  1. to_numeric() - 提供功能以安全地将非数值类型(例如字符串)转换为合适的数值类型。(另见 to_datetime()to_timedelta()。)
  2. astype() - (几乎)任何类型转换为(几乎)任何其他类型(即使这样做不一定合理)。还允许你将类型转换为分类类型(非常有用)。
  3. infer_objects() - 一个实用方法,如果可能的话,将包含 python 对象的列转换为 pandas 类型。
  4. convert_dtypes() - dataframe 列转换为支持 pd.na(pandas 的对象,用于表示缺失值)的“最佳可能”数据类型。

1.to_numeric()

将非数值对象(如字符串)转换为整数或浮点数的最好方法是使用 pandas 中的 to_numeric() 函数。

这个函数会尝试将非数值对象(如字符串)转换为适当的整数或浮点数。

基本用法

to_numeric() 的输入可以是一个 series 或者一个 dataframe 的单列。

s = pd.series(["8", "6", "7.5", "3", "0.9"])  # 合字符串和数值
s = pd.to_numeric(s)  # 转换为浮点值

可以看到,返回了一个新的 series。你可以将其赋值给一个变量或列名以便继续使用:

my_series = pd.to_numeric(my_series)

你也可以使用 apply() 方法来转换 dataframe 的多列:

df = df.apply(pd.to_numeric)  # 转换 `dataframe` 的所有列

或者只转换特定的列:

df[["a", "b"]] = df[["a", "b"]].apply(pd.to_numeric)

只要你的值都可以被转换,这可能就是你需要的所有操作。

错误处理

但如果有些值无法转换为数值类型怎么办?

to_numeric() 接受一个 errors 关键字参数,允许你强制非数值值为 nan,或者简单地忽略包含这些值的列。

以下是一个使用字符串 series 的示例,该 series 有对象数据类型:

s = pd.series(['1', '2', '4.7', 'pandas', '10'])

默认行为是在无法转换值时引发异常。在这种情况下,它无法处理字符串 ‘pandas’:

pd.to_numeric(s, errors='raise')

valueerror: unable to parse string

与其失败,我们可能希望 ‘pandas’ 被视为缺失或无效的数值,并将其转换为 nan,如下所示:

pd.to_numeric(s, errors='coerce')

第三个选项是,如果遇到无效值,则忽略操作:

pd.to_numeric(s, errors='ignore')

原始 series 将保持不变。

最后一个选项特别适用于转换整个 dataframe,但不知道哪些列可以可靠地转换为数值类型。

在这种情况下,只需写:

df.apply(pd.to_numeric, errors='ignore')

该函数将应用于 dataframe 的每一列。可以转换为数值类型的列将被转换,而不能转换的列(例如,它们包含非数字字符串或日期)将保持不变。

下采样 (downcasting)

默认情况下,使用 to_numeric() 换时,你会得到 int64float64 数据类型(或者平台原生的任何整数宽度)。

这通常是你要的结果,但如果你想要节省内存并使用更紧凑的数据类型,比如 float32int8 么办?

to_numeric() 给你选择下采样的选项,可以转换为 'integer''signed''unsigned''float'。以下是一个简单的整数类型 series 示例:

s = pd.series([1, 2, -7])

下采样到 'integer' 使用可以容纳值的最小可能整数:

pd.to_numeric(s, downcast='integer')

下采样到 'float' 同样选择比正常浮点类型更小的类型:

pd.to_numeric(s, downcast='float')

结果将是 float32

2.astype()

astype() 方法允许你明确指定 dataframe 或 series 的数据类型。它非常灵活,可以尝试从一种类型转换为另一种类型。

基本用法

只需选择一个类型:你可以使用 numpy 数据类型(例如 np.int16)、一些 python 类型(例如 bool),或者 pandas 特定的类型(如分类数据类型)。

在你想转换的对象上调用该方法,astype() 将尝试并为你进行转换:

# 将所有 dataframe 列转换为 int64 类型
df = df.astype(int)

# 列 "a" 转换为 int64 类型,将列 "b" 转换为复数类型
df = df.astype({"a": int, "b": complex})

# 将 series 转换为 float16 类型
s = s.astype(np.float16)

# 将 series 转换为 python 字符串
s = s.astype(str)

# 将 series 转换为分类类型 - 请参阅文档以获取更多详细信息
s = s.astype('category')

请注意我说的是“尝试”——如果 astype() 不知道如何转换 series 或 dataframe 中的值,它将引发错误。

例如,如果你有一个 naninf ,尝试将其转换为整数时会得到错误。

从 pandas 0.20.0 开始,可以通过传递 errors='ignore' 来抑制此错误。你的原始对象将保持不变。

注意事项

astype() 是强大的,但它有时会“错误地”转换值。例如:

>>> s = pd.series([1, 2, -7])
>>> s
0    1
1    2
2   -7
dtype: int64

这些是小整数,那么将其转换为无符号 8 位类型以节省内存如何?

>>> s.astype(np.uint8)
0     1
1     2
2    249
dtype: uint8

转换成功了,但 -7 绕了一圈变成了 249(即 (2^8 - 7))!

尝试使用 pd.to_numeric(s, downcast='unsigned') 行下采样可能会避免这个错误。

3.infer_objects()

pandas 版本 0.21.0 引入了 infer_objects() 方法,用于将 dataframe 中具有对象数据类型的列转换为更具体的数据类型(软转换)。

例如,这里有一个 dataframe,包含两列对象类型。一列持有实际的整数,另一列持有表示整数的字符串:

>>> df = pd.dataframe({'a': [7, 1, 5], 'b': ['3', '2', '1']}, dtype='object')
>>> df.dtypes
a    object
b    object
dtype: object

使用 infer_objects(),你可以将列 ‘a’ 的类型更改为 int64:

>>> df = df.infer_objects()
>>> df.dtypes
a    int64
b    object
dtype: object

列 ‘b’ 保持不变,因为其值是字符串,而不是整数。如果你想强制将两列都转换为整数类型,可以使用 df.astype(int)

4.convert_dtypes()

版本 1.0 及以上包括一个方法 convert_dtypes(),用于将 series 和 dataframe 列转换为支持 pd.na 缺失值的最佳可能数据类型。

这里的“最佳可能”是指最适合存储这些值的数据类型。例如,如果所有值都是整数(或缺失值),则会转换为 pandas 整数类型;如果 python 整数对象的列被转换为 int64,numpy int32 值的列将变为 pandas 数据类型 int32

对于我们的对象 dataframe df,我们得到以下结果:

>>> df.convert_dtypes().dtypes
a    int64
b    string
dtype: object

由于列 ‘a’ 包含整数值,因此被转换为 int64 类型(能够存储缺失值,与 int64 不同)。

列 ‘b’ 包含字符串对象,因此被转换为 pandas string 类型。

默认情况下,此方法会从每列的对象值推断类型。我们可以通过传递 infer_objects=false 来更改这一点:

>>> df.convert_dtypes(infer_objects=false).dtypes
a    object
b    string
dtype: object

现在列 ‘a’ 仍然是一个对象列:pandas 知道它可以被描述为一个整数列(内部运行了 infer_dtype),但没有推断出它应该具有的确切数据类型,因此没有转换它。列 ‘b’ 再次被转换为 string 类型,因为它被识别为持有字符串值。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com