python - 確認 - データフレーム 型変換




Pandas の列のデータ型を変更する (4)

私は、リストのリストとして表現されたテーブルをPandas DataFrameに変換したいと思います。 非常に単純な例として、

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

列を適切な型に変換する最良の方法は何ですか、この場合は列2と列3を浮動小数点数に変換しますか? DataFrameに変換する際に型を指定する方法はありますか? または、最初にDataFrameを作成し、各列のタイプを変更するために列をループする方が良いでしょうか? 理想的には、何百もの列が存在する可能性があり、どの列がどの型であるかを正確に指定したくないため、これを動的に実行したいと考えています。 私が保証できるのは、各列に同じ型の値が含まれているということだけです。


あなたはパンダのタイプを変換するための3つの主なオプションがあります。

1. to_numeric()

DataFrameの1つ以上の列を数値に変換する最も良い方法は、 pandas.to_numeric()を使用することpandas.to_numeric()

基本的な使用法

to_numeric()への入力はSeriesまたは単一の列です。 新しいSeriesが返されるので、出力を変数に代入してください。

# convert Series
my_series = pd.to_numeric(my_series)

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

また、それをapplyてDataFrameの複数の列を変換することもできapply

# 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)

あなたの価値がすべて変換される限り、それはおそらくあなたが必要とするものです。

エラー処理

しかし、いくつかの値を数値型に変換できない場合はどうなりますか?

to_numericerrors以外の数値をNaNにするか、単にこれらの値を含む列を無視することもできます。

次に、dtypeオブジェクトを持つ一連の文字列sを使用する例を示します。

>>> 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

失敗するのではなく、「パンダ」が欠けている/悪い数値と見なされることがあります。 無効な値を次のようにNaN強制することができます。

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

errorsの3番目のオプションは、無効な値に遭遇した場合に操作を無視することです。

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

この最後のオプションは、DataFrame全体を変換したいが、どの列を確実に数値型に変換できるかわからない場合に特に便利です。 その場合は次のように書いてください:

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

この関数は、DataFrameの各列に適用されます。 数値型に変換可能な列は変換されますが、変換できない列(たとえば、数字以外の文字列や日付など)はそのまま残ります。

ダウンキャスティング

デフォルトでは、 to_numeric()で変換すると、 int64またはfloat64 dtype(または、プラットフォームに固有の整数の幅to_numeric()が与えられます。

これは通常あなたが望むものですが、メモリを節約し、よりコンパクトなdtype( float32int8など)を使用する場合はどうすればよいでしょうか?

to_numeric()は、 'integer'、 'signed'、 'unsigned'、 'float'のいずれかにダウンキャストするオプションを提供します。 整数型s単純な系列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など)を使用できます。

変換したいオブジェクトのメソッドを呼び出すと、 astype()があなたのために変換しようとします:

# 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')

「試してみてください」と言いました - astypeがSeriesまたはDataFrameの値を変換する方法を知らないと、エラーが発生します。 たとえば、 NaNまたはinf値を持つ場合、整数に変換しようとするとエラーが発生します。

パンダ0.20.0以降、このエラーはerrors='ignore'を渡すことで抑止できます。 オリジナルのオブジェクトは元に戻りません。

注意してください

astype()は強力ですが、値を「間違って」変換することがあります。 例えば:

>>> 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(つまり2 8 - 7)になるようにラップされました!

代わりにpd.to_numeric(s, downcast='unsigned')を使用してダウンキャストしようとすると、このエラーを防ぐことができます。

infer_objects()

バージョン0.21.0のpandasは、オブジェクトデータ型を持つDataFrameの列をより具体的な型(ソフト変換)に変換するためのinfer_objects()メソッドを導入しました。

たとえば、オブジェクト型の2つの列を持つDataFrameを作成します。 1つは実際の整数を保持し、もう1つは整数を表す文字列を保持します。

>>> df = pd.DataFrame({'a': [7, 1, 5], 'b': ['3','2','1']}, dtype='object')
>>> df.dtypes
a    object
b    object
dtype: object

infer_objects()を使用して、カラム 'a'のタイプをinfer_objects()変更できます:

>>> df = df.infer_objects()
>>> df.dtypes
a     int64
b    object
dtype: object

列 'b'は、その値が整数ではなく文字列であるため、単独で残されています。 両方の列を整数型に変換しようとする場合は、代わりにdf.astype(int)使用できます。


これはどう?

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

以下のコードは列のデータ型を変更します。

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

データ型の代わりに、str、float、intなどのデータ型を与えることができます。


引数として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'])




casting