【问题标题】:Python Pandas inferring column datatypesPython Pandas 推断列数据类型
【发布时间】:2016-05-02 09:13:32
【问题描述】:

我正在将 JSON 文件读入数据帧。数据框可能有一些字符串(对象)类型的列、一些数字(int64 和/或 float64)和一些日期时间类型的列。读入数据时,数据类型往往不正确(即日期时间、整数和浮点数通常会存储为“对象”类型)。我想报告这种可能性。 (即一列在数据框中作为“对象”(字符串),但它实际上是一个“日期时间”)。

我遇到的问题是,当我使用 pd.to_numericpd.to_datetime 时,它们都会评估并尝试转换列,很多时候它最终取决于我最后调用的两个中的哪一个......(我打算使用 convert_objects() 哪个可行,但已折旧,因此需要更好的选择)。

我用来评估数据框列的代码是(我意识到下面的很多内容都是多余的,但为了可读性我已经这样写了):

try:
   inferred_type = pd.to_datetime(df[Field_Name]).dtype
   if inferred_type == "datetime64[ns]":
      inferred_type = "DateTime"
except:
   pass
try:
   inferred_type = pd.to_numeric(df[Field_Name]).dtype
   if inferred_type == int:
      inferred_type = "Integer"
   if inferred_type == float:
      inferred_type = "Float"
except:
   pass

【问题讨论】:

  • 很遗憾它已被弃用。这是一种光荣的方法。
  • convert_objects 已被 infer_objects 弃用,不是
  • @itzjustricky infer_objects 甚至不会将 ['1', '2', '3'] 识别为数字。 pd.DataFrame(['1', '2', '3']).infer_objects().dtypes 返回“对象”

标签: python pandas profiling


【解决方案1】:

我遇到了同样的问题,即必须事先确定类型未知的传入数据的列类型(在我的例子中来自读取的数据库)。我在这里找不到一个好的答案,或者查看 Pandas 源代码。我用这个函数解决了它:

def _get_col_dtype(col):
        """
        Infer datatype of a pandas column, process only if the column dtype is object. 
        input:   col: a pandas Series representing a df column. 
        """

        if col.dtype == "object":
            # try numeric
            try:
                col_new = pd.to_datetime(col.dropna().unique())
                return col_new.dtype
            except:
                try:
                    col_new = pd.to_numeric(col.dropna().unique())
                    return col_new.dtype
                except:
                    try:
                        col_new = pd.to_timedelta(col.dropna().unique())
                        return col_new.dtype
                    except:
                        return "object"
        else:
            return col.dtype

【讨论】:

    【解决方案2】:

    根据 BeigeBruceWayne 的回答处理

    df_types = pd.DataFrame(df_final.apply(pd.api.types.infer_dtype, axis=0)).reset_index().rename(columns={'index': 'column', 0: 'type'})
    
    loop_types = df_types.values.tolist()
    
    for col in loop_types:
        if col[1] == 'mixed':
            pass
        else:
            if col[1] == 'decimal':
                data_type = 'float64'
            elif col[1] == 'string':
                data_type = 'str'
            elif col[1] == 'integer':
                data_type = 'int'
            elif col[1] == 'floating':
                data_type = 'float64'
            elif col[1] == 'date':
                data_type = 'datetime64'
            else:
                data_type = col[1]
            df_final[col[0]] = df_final[col[0]].astype(data_type)
    
    

    【讨论】:

      【解决方案3】:

      在 Pandas API 的深处,实际上有一个功能做得不错的函数。

      import pandas as pd
      
      infer_type = lambda x: pd.api.types.infer_dtype(x, skipna=True)
      df.apply(infer_type, axis=0)
      
      
      # DataFrame with column names & new types
      
      df_types = pd.DataFrame(df.apply(pd.api.types.infer_dtype, axis=0)).reset_index().rename(columns={'index': 'column', 0: 'type'})
      

      http://pandas.pydata.org/pandas-docs/stable/generated/pandas.api.types.infer_dtype.html#pandas.api.types.infer_dtype

      自从

      推理规则与普通Series/DataFrame构造时相同。

      考虑 to_numeric 用于 int/floats
      例如:df['amount'] = pd.to_numeric(df['amount'], errors='ignore')

      【讨论】:

      • 似乎对我不起作用,返回所有字符串,即使有一些 int、float 和 bool 列
      【解决方案4】:

      让它推断 dtypes 的一种解决方案是让它使用 StringIO 将数据写入 CSV,然后再读回。

      【讨论】:

        【解决方案5】:

        或者:Pandas 允许您在创建数据框时明确定义数据类型。您传入一个字典,其中列名作为键,所需的数据类型作为值。

        Documentation Here 用于标准构造函数

        或者您可以在导入数据框后转换列的类型

        例如: df['field_name'] = df['field_name'].astype(np.date_time)

        【讨论】:

          【解决方案6】:

          试试例如

          df['field_name'] = df['field_name'].astype(np.float64)
          

          (假设import numpy as np

          【讨论】:

          • 谢谢。如何使用上述策略检查日期时间?
          • df['field_name'] = pd.to_datetime(df['field_name'])
          • 仍然遇到同样的问题。列似乎可以作为日期时间和浮点类型进行评估。
          • 等一下,您是否尝试转换列以查看它是否引发错误?您是否建议您不知道您的数据列有哪些类型?尴尬了;我建议你先定义你的数据集。例如,Epoch time 中的日期可能看起来像 int,因此转换为 int 或转换为 datetime 都可以。
          • 是的,这是我的方法(代替更好的解决方案)...我不认为这是做事的最佳方式,但我根本无法控制数据集将被读入数据帧(因此出现问题)。欢迎任何其他建议!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-02-03
          • 1970-01-01
          • 2016-11-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-08
          相关资源
          最近更新 更多