Python Pandas推断列数据类型

时间:2016-01-25 21:54:04

标签: python pandas profiling

我正在将JSON文件读入数据帧。数据框可能包含一些String(对象)类型列,一些Numeric(int64和/或float64)以及一些日期时间类型列。读入数据时,数据类型通常不正确(即datetime,int和float通常存储为“object”类型)。我想报告这种可能性。 (即列在数据帧中为“object”(String),但它实际上是“datetime”)。

我遇到的问题是,当我使用 pd.to_numeric pd.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

6 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,即在我的情况下从db读取中必须找出事先不知道类型的数据的列类型。无法在SO上找到一个好的答案,或者通过查看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

答案 1 :(得分:1)

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

Documentation Here用于标准构造函数

或者您可以在导入数据框

后转换列的类型

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

在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

答案 4 :(得分:0)

尝试例如。

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

(假设import numpy as np

答案 5 :(得分:0)

解决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)