web-dev-qa-db-ja.com

Python Pandas列のデータ型を推測する

JSONファイルをデータフレームに読み込んでいます。データフレームには、いくつかの文字列(オブジェクト)タイプの列、いくつかの数値(int64および/またはfloat64)、およびいくつかの日時タイプの列が含まれる場合があります。データが読み込まれると、データ型が正しくないことがよくあります(つまり、datetime、int、floatは「オブジェクト」型として格納されることがよくあります)。この可能性について報告したいと思います。 (つまり、列は「オブジェクト」(文字列)としてデータフレームにありますが、実際には「日時」です)。

私が抱えている問題は、pd.to_numericおよびpd.to_datetimeどちらも列を評価して変換しようとしますが、最後に呼び出した2つのうちどちらに依存するかによって何度も終了します...( 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
12
Calamari

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構築時と同じです。

int/floatの場合は to_numeric を検討してください
例:df['amount'] = pd.to_numeric(df['amount'], errors='ignore')

4
BeigeBruceWayne

私の場合、読み取られたデータベースから、タイプが事前にわからない受信データの列タイプを把握する必要があるという同じ問題に遭遇しました。 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
3
PabTorre

Dtypesを推測するための1つの解決策は、StringIOを使用してCSVにデータを書き込み、それを読み戻すことです。

1
Daniel H

または、Pandasを使用すると、データフレームを作成するときにデータ型を明示的に定義できます。キーとして列名を、値として目的のデータ型を使用してディクショナリを渡します。

ドキュメントはこちら 標準コンストラクターの場合

または、データフレームにインポートした後、列のタイプをキャストできます

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

1
Derrick Cheek

たとえば、試してみてください。

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

(仮定して import numpy as np

0
zebralove79

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)

0
Joe