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()を選びます。