HOWTO · Pandas
Pandas Dataframe を NumPy 配列に変換する方法
Pandas DataFrame を to_numpy() で NumPy 配列に変換し、そのインデックスを含めるか、to_records() で構造化レコードを作成します。
このページの内容
通常のNumPy配列に変換するには、DataFrame.to_numpy()を呼び出します。既存コードを保守する場合は従来のDataFrame.valuesプロパティを使えます。名前付きフィールドが必要なら、DataFrame.to_records()を選びます。例では固定データを使い、pandasとNumPyが必要です。通常の配列はdtypeが1つだけなので、列の型が混在している場合は共通のdtypeで表現されます。
DataFrame.to_numpy()でNumPy配列に変換する
to_numpy()は、表のデータを2次元のNumPy配列として返します。行はDataFrameの行順、列はDataFrameの列順に並びます。配列の形状は(行数, 列数)で、DataFrameのインデックスと列ラベルは含まれません。返されるオブジェクトはndarrayなので、そのまま後続のNumPy関数に渡せます。
次の例では、小さな表を作成して値を変換し、配列、形状、戻り値の型を表示します。
import pandas as pd
df = pd.DataFrame({"name": ["Ada", "Lin"], "score": [91, 88]})
array = df.to_numpy()
print(array)
print(array.shape)
print(type(array))
[['Ada' 91]
['Lin' 88]]
(2, 2)
<class 'numpy.ndarray'>
特定のdtypeが必要な場合は、to_numpy()にdtype=を渡します。たとえば、df.to_numpy(dtype="float64")のように指定します。これは値をそのdtypeに変換するようNumPyに指示するため、すべての列の値を表現できるdtypeを選んでください。文字列と数値が混在している場合、数値型だけでは変換せずにすべての値を表現できません。そのため、既定の共通dtypeがobjectになることがあります。
従来のDataFrame.valuesとインデックスの追加
DataFrame.valuesはプロパティなので、括弧を付けずにアクセスします。表形式のデータを配列として返しますが、to_numpy()を使うと変換の意図が明確になり、新しいコードではこちらの表記が推奨されます。既存コードでは、valuesを属性として引き続き読み取れます。
インデックスの値を列として含めるには、変換の前にreset_index()を呼び出します。既定では、元のインデックスが先頭の列に入り、新しい既定の整数インデックスが作成されます。列名を分かりやすくしたい場合は、先にインデックス名を変更してください。オプションについてはreset_index()を参照してください。
import pandas as pd
df = pd.DataFrame({"score": [91, 88]}, index=["Ada", "Lin"])
legacy_array = df.values
with_index = df.reset_index().to_numpy()
print(legacy_array)
print(with_index)
[[91]
[88]]
[['Ada' 91]
['Lin' 88]]
インデックスラベルは文字列で、スコアの値は整数なので、通常の配列では共通のdtypeが必要になり、objectが使われることがあります。インデックスが含まれるのはreset_index()を実行した後だけです。元のDataFrameをそのまま変換しても、インデックスラベルは入りません。列ごとの型と名前を保ったまま扱いたい場合は、構造化レコード配列を使います。
DataFrame.to_records()で構造化NumPy配列を作成する
to_records()は、DataFrameの各列に名前付きフィールドを持つ構造化NumPy配列を返します。既定では、indexという名前のフィールドにインデックスも含まれます。フィールド名を使って列にアクセスでき、構造化dtypeにはそれぞれの型が記録されます。そのため、列の位置に頼らず名前でフィールドを選びたいコードに適しています。
import pandas as pd
df = pd.DataFrame({"name": ["Ada", "Lin"], "score": [91, 88]})
records = df.to_records()
print(records["name"])
print(records["score"])
print(records.dtype.names)
['Ada' 'Lin']
[91 88]
('index', 'name', 'score')
インデックスを除外するにはindex=Falseを指定します。インデックスフィールドのdtypeを指定する必要がある場合は、index_dtypes=を渡します。一般的な配列にはto_numpy()を使い、名前付きフィールドや列ごとのdtype情報が必要な場合はto_records()を選びます。