首页 文章

更改Pandas中列的数据类型

提问于
浏览
457

我想将表格(表示为列表列表)转换为Pandas DataFrame . 作为一个非常简单的例子:

a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
df = pd.DataFrame(a)

将列转换为适当类型的最佳方法是什么,在这种情况下,将第2列和第3列转换为浮点数?有没有办法在转换为DataFrame时指定类型?或者,最好先创建DataFrame,然后循环遍历列以更改每列的类型?理想情况下,我想以动态方式执行此操作,因为可能有数百列,我不想确切地指定哪些列属于哪种类型 . 我可以保证的是,每列包含相同类型的值 .

6 回答

  • 5

    这是一个函数,它将DataFrame和列列表作为参数,并将列中的所有数据强制转换为数字 .

    # df is the DataFrame, and column_list is a list of columns as strings (e.g ["col1","col2","col3"])
    # dependencies: pandas
    
    def coerce_df_columns_to_numeric(df, column_list):
        df[column_list] = df[column_list].apply(pd.to_numeric, errors='coerce')
    

    所以,举个例子:

    import pandas as pd
    
    def coerce_df_columns_to_numeric(df, column_list):
        df[column_list] = df[column_list].apply(pd.to_numeric, errors='coerce')
    
    a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
    df = pd.DataFrame(a, columns=['col1','col2','col3'])
    
    coerce_df_columns_to_numeric(df, ['col2','col3'])
    
  • 11

    您有三个主要选项来转换pandas中的类型 .


    1. to_numeric()

    将DataFrame的一个或多个列转换为数值的最佳方法是使用pandas.to_numeric() .

    此函数将尝试根据需要将非数字对象(如字符串)更改为整数或浮点数 .

    基本用法

    to_numeric() 的输入是DataFrame的Series或单列 .

    >>> s = pd.Series(["8", 6, "7.5", 3, "0.9"]) # mixed string and numeric values
    >>> s
    0      8
    1      6
    2    7.5
    3      3
    4    0.9
    dtype: object
    
    >>> pd.to_numeric(s) # convert everything to float values
    0    8.0
    1    6.0
    2    7.5
    3    3.0
    4    0.9
    dtype: float64
    

    如您所见,返回一个新系列 . 请记住将此输出分配给变量或列名称以继续使用它:

    # convert Series
    my_series = pd.to_numeric(my_series)
    
    # convert column "a" of a DataFrame
    df["a"] = pd.to_numeric(df["a"])
    

    您还可以使用它通过 apply() 方法转换DataFrame的多个列:

    # convert all columns of DataFrame
    df = df.apply(pd.to_numeric) # convert all columns of DataFrame
    
    # convert just columns "a" and "b"
    df[["a", "b"]] = df[["a", "b"]].apply(pd.to_numeric)
    

    只要你的 Value 都可以转换,那可能就是你所需要的 .

    错误处理

    但是,如果某些值无法转换为数字类型呢?

    to_numeric() 也采用 errors 关键字参数,允许您强制非数字值为 NaN ,或者只是忽略包含这些值的列 .

    这是一个使用一系列字符串 s 的示例,其中包含对象dtype:

    >>> s = pd.Series(['1', '2', '4.7', 'pandas', '10'])
    >>> s
    0         1
    1         2
    2       4.7
    3    pandas
    4        10
    dtype: object
    

    如果无法转换值,则默认行为是提升 . 在这种情况下,它无法处理字符串'pandas':

    >>> pd.to_numeric(s) # or pd.to_numeric(s, errors='raise')
    ValueError: Unable to parse string
    

    我们可能希望将'pandas'视为缺失/错误的数值,而不是失败 . 我们可以使用 errors 关键字参数将无效值强制转换为 NaN

    >>> pd.to_numeric(s, errors='coerce')
    0     1.0
    1     2.0
    2     4.7
    3     NaN
    4    10.0
    dtype: float64
    

    errors 的第三个选项只是在遇到无效值时忽略该操作:

    >>> pd.to_numeric(s, errors='ignore')
    # the original Series is returned untouched
    

    当您想要转换整个DataFrame时,最后一个选项特别有用,但不知道哪些列可以可靠地转换为数字类型 . 在这种情况下,只需写:

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

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

    向下倾斜

    默认情况下,使用 to_numeric() 进行转换将为您提供 int64float64 dtype(或您的平台本机的任何整数宽度) .

    这通常是你想要的,但是如果你想节省一些内存并使用更紧凑的dtype,比如 float32int8 呢?

    to_numeric() 为您提供向下转换为'integer','signed','unsigned','float'的选项 . 这是一个简单系列 s 整数类型的示例:

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

    向下转换为'整数'使用可以保存值的最小可能整数:

    >>> pd.to_numeric(s, downcast='integer')
    0    1
    1    2
    2   -7
    dtype: int8
    

    向下'漂浮'同样选择一个小于正常的浮动类型:

    >>> pd.to_numeric(s, downcast='float')
    0    1.0
    1    2.0
    2   -7.0
    dtype: float32
    

    2. astype()

    astype()方法使您能够明确了解您希望DataFrame或Series具有的dtype . 它非常通用,你可以尝试从一种类型转向另一种类型 .

    基本用法

    只需选择一种类型:您可以使用NumPy dtype(例如 np.int16 ),某些Python类型(例如bool)或pandas特定类型(例如分类dtype) .

    在要转换的对象上调用方法,_484364将尝试为您转换它:

    # convert all DataFrame columns to the int64 dtype
    df = df.astype(int)
    
    # convert column "a" to int64 dtype and "b" to complex type
    df = df.astype({"a": int, "b": complex})
    
    # convert Series to float16 type
    s = s.astype(np.float16)
    
    # convert Series to Python strings
    s = s.astype(str)
    
    # convert Series to categorical type - see docs for more details
    s = s.astype('category')
    

    注意我说"try" - 如果 astype() 不知道如何转换Series或DataFrame中的值,它将引发错误 . 例如,如果您有 NaNinf 值,则在尝试将其转换为整数时会出错 .

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

    小心点

    astype() 功能强大,但有时会转换值"incorrectly" . 例如:

    >>> 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(即28 - 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) .

  • 540

    如何创建两个数据框,每个数据框的列都有不同的数据类型,然后将它们一起添加?

    d1 = pd.DataFrame(columns=[ 'float_column' ], dtype=float)
    d1 = d1.append(pd.DataFrame(columns=[ 'string_column' ], dtype=str))
    

    Results

    In[8}:  d1.dtypes
    Out[8]: 
    float_column     float64
    string_column     object
    dtype: object
    

    创建数据框后,可以使用第1列中的浮点变量和第2列中的字符串(或所需的任何数据类型)填充它 .

  • 400

    当我使用've only needed to specify specific columns, and I want to be explicit, I'时(每DOCS LOCATION):

    dataframe = dataframe.astype({'col_name_1':'int','col_name_2':'float64', etc. ...})
    

    所以,使用原始问题,但为其提供列名...

    a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
    df = pd.DataFrame(a, columns=['col_name_1', 'col_name_2', 'col_name_3'])
    df = df.astype({'col_name_2':'float64', 'col_name_3':'float64'})
    
  • 25

    这个怎么样?

    a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
    df = pd.DataFrame(a, columns=['one', 'two', 'three'])
    df
    Out[16]: 
      one  two three
    0   a  1.2   4.2
    1   b   70  0.03
    2   x    5     0
    
    df.dtypes
    Out[17]: 
    one      object
    two      object
    three    object
    
    df[['two', 'three']] = df[['two', 'three']].astype(float)
    
    df.dtypes
    Out[19]: 
    one       object
    two      float64
    three    float64
    
  • 2

    下面的代码将更改列的数据类型 .

    df[['col.name1', 'col.name2'...]] = df[['col.name1', 'col.name2'..]].astype('data_type')
    

    代替数据类型,你可以给你的数据类型 . 你想要什么像str,float,int等 .

相关问题