开发者

在pandas中更改列类型方式

目录
  • 1.to_numeric()
    • 基本用法
    • 错误处理
    • 下采样 (Downcasting)
  • 2.astype()
    • 基本用法
    • 注意事项
  • 3.infer_objects()
    • 4.convert_dtypes()
      • 总结

        在 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')
        
        javascript

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

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

        原始 Series 将保持不变。

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

        在这种情况下,只需写:

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

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

        下采样 (Downcasting)

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

        这通常是你要的结果,但如果你想要节省内存并使用更紧凑的数据类型,比如 float3编程客栈2int8 么办?

        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' 来抑制此错误。KnkkON你的原始对象将保持不变。

        注意事项

        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')
        >>&gphpt; 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 类型,因为它被识别为持有字符串值。

        总结

        以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新开发

        开发排行榜