【问题标题】:How to force pandas read_csv to use float32 for all float columns?如何强制 pandas read_csv 对所有浮点列使用 float32?
【发布时间】:2015-08-10 06:05:10
【问题描述】:

因为

  • 我不需要双精度
  • 我的机器内存有限,我想处理更大的数据集
  • 我需要将提取的数据(作为矩阵)传递给 BLAS 库,单精度的 BLAS 调用比双精度等效调用快 2 倍。

请注意,并非原始 csv 文件中的所有列都具有浮点类型。我只需要将 float32 设置为浮点列的默认值。

【问题讨论】:

    标签: python numpy pandas


    【解决方案1】:

    试试:

    import numpy as np
    import pandas as pd
    
    # Sample 100 rows of data to determine dtypes.
    df_test = pd.read_csv(filename, nrows=100)
    
    float_cols = [c for c in df_test if df_test[c].dtype == "float64"]
    float32_cols = {c: np.float32 for c in float_cols}
    
    df = pd.read_csv(filename, engine='c', dtype=float32_cols)
    

    这首先读取 100 行数据的样本(根据需要进行修改)以确定每一列的类型。

    它会创建一个包含“float64”列的列表,然后使用字典理解来创建一个字典,其中这些列作为键,“np.float32”作为每个键的值。

    最后,它使用“c”引擎(将 dtype 分配给列所需)读取整个文件,然后将 float32_cols 字典作为参数传递给 dtype。

    df = pd.read_csv(filename, nrows=100)
    >>> df
       int_col  float1 string_col  float2
    0        1     1.2          a     2.2
    1        2     1.3          b     3.3
    2        3     1.4          c     4.4
    
    >>> df.info()
    <class 'pandas.core.frame.DataFrame'>
    Int64Index: 3 entries, 0 to 2
    Data columns (total 4 columns):
    int_col       3 non-null int64
    float1        3 non-null float64
    string_col    3 non-null object
    float2        3 non-null float64
    dtypes: float64(2), int64(1), object(1)
    
    df32 = pd.read_csv(filename, engine='c', dtype={c: np.float32 for c in float_cols})
    >>> df32.info()
    <class 'pandas.core.frame.DataFrame'>
    Int64Index: 3 entries, 0 to 2
    Data columns (total 4 columns):
    int_col       3 non-null int64
    float1        3 non-null float32
    string_col    3 non-null object
    float2        3 non-null float32
    dtypes: float32(2), int64(1), object(1)
    

    【讨论】:

      【解决方案2】:

      @Alexander's 是一个很好的答案。某些列可能需要精确。如果是这样,您可能需要在列表理解中添加更多条件以排除 anyall 内置插件很方便的某些列:

      float_cols = [c for c in df_test if all([df_test[c].dtype == "float64", 
                   not df_test[c].name == 'Latitude', not df_test[c].name =='Longitude'])]           
      

      【讨论】:

        【解决方案3】:

        如果您不关心列顺序,还有df.select_dtypes 可以避免read_csv 两次:

        import pandas as pd
        
        df = pd.read_csv("file.csv")
        
        df_float = df.select_dtypes(include=float).astype("float32")
        df_not_float = df.select_dtypes(exclude=float)
        
        df = df_float.join(df_not_float)
        

        或者,如果您想将 所有 个非字符串列(例如整数列)转换为浮点数:

        import pandas as pd
        
        df = pd.read_csv("file.csv")
        
        df_not_str = df.select_dtypes(exclude=object).astype("float32")
        df_str = df.select_dtypes(include=object)
        
        df = df_not_str.join(df_str)
        

        【讨论】:

          【解决方案4】:

          这是一个不依赖于.join 或不需要读取文件两次的解决方案:

          float64_cols = df.select_dtypes(include='float64').columns
          mapper = {col_name: np.float32 for col_name in float64_cols}
          df = df.astype(mapper)
          

          或者作为单线踢:

          df = df.astype({c: np.float32 for c in df.select_dtypes(include='float64').columns})
          

          【讨论】:

            【解决方案5】:

            我认为调用 dtypes 比 jorijnsmit 的解决方案更有效...

            jorijnsmit 的:

            %%timeit
            df.astype({c: 'float32' for c in df.select_dtypes(include='float64').columns})
            754 µs ± 6.06 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
            

            调用数据类型:

            %%timeit
            df.astype({c: 'float32' for c in df.dtypes.index[df.dtypes == 'float64']})
            538 µs ± 343 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
            

            【讨论】:

              猜你喜欢
              • 2019-07-08
              • 1970-01-01
              • 1970-01-01
              • 2019-08-22
              • 2020-05-01
              • 2019-07-28
              • 2019-09-15
              • 2020-07-03
              • 2021-04-18
              相关资源
              最近更新 更多