NumPy配列ndarrayとPythonのリストを相互に変換
NumPy配列ndarray
とPythonのリストlist
を相互に変換する方法について説明する。
なお、便宜上「変換」という言葉を使っているが、実際は元のオブジェクトはそのままで新たな型のオブジェクトが生成される。
本記事のサンプルコードのNumPyのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。
import numpy as np
print(np.__version__)
# 1.26.1
リストをNumPy配列ndarrayに変換: numpy.array()
NumPy配列numpy.ndarray
を生成するnumpy.array()
の引数にPythonリスト型のオブジェクトを渡すと、リストを元にndarray
が生成される。
l_1d = [0, 1, 2]
a_1d = np.array(l_1d)
print(a_1d)
# [0 1 2]
print(type(a_1d))
# <class 'numpy.ndarray'>
print(a_1d.dtype)
# int64
生成されるndarray
のデータ型dtype
は元のリストから自動で決定されるが、引数dtype
で指定することもできる。
NumPyのデータ型dtype
については以下の記事を参照。
a_1d_f = np.array(l_1d, dtype=float)
print(a_1d_f)
# [0. 1. 2.]
print(a_1d_f.dtype)
# float64
2次元以上の多次元配列でも同様。
l_2d = [[0, 1, 2], [3, 4, 5]]
a_2d = np.array(l_2d)
print(a_2d)
# [[0 1 2]
# [3 4 5]]
Pythonのリストで表現する多次元配列は単なるネストしたリスト(リストのリスト)なので、リストの要素数が一致していなくても問題ないが、それをそのままnumpy.array()
に渡すとValueError
となる(NumPy1.24
以降)。
- NumPy 1.24 Release Notes - Expired deprecations — NumPy v1.26 Manual
- NEP 34 — Disallow inferring dtype=object from sequences — NumPy Enhancement Proposals
l_2d_jagged = [[0, 1, 2], [3, 4]]
# a_2d_jagged = np.array(l_2d_jagged)
# ValueError: setting an array element with a sequence.
# The requested array has an inhomogeneous shape after 1 dimensions.
# The detected shape was (2,) + inhomogeneous part.
dtype=object
とすると、要素数がバラバラのリスト型オブジェクトを要素としたndarray
が生成される。バージョン1.24
より前はデフォルトでこの挙動だった。
a_2d_jagged = np.array(l_2d_jagged, dtype=object)
print(a_2d_jagged)
# [list([0, 1, 2]) list([3, 4])]
print(a_2d_jagged.shape)
# (2,)
print(a_2d_jagged.dtype)
# object
print(a_2d_jagged[0])
# [0, 1, 2]
print(type(a_2d_jagged[0]))
# <class 'list'>
NumPy配列ndarrayをリストに変換: tolist()
NumPy配列ndarray
のメソッドtolist()
は、リスト型のオブジェクトを返す。
元のndarray
の次元数に応じて、ネストしたリストが返される。
以下の例ではarange()
とreshape()
でNumPy配列ndarray
を生成している。
1次元の場合。
a_1d = np.arange(3)
print(a_1d)
# [0 1 2]
l_1d = a_1d.tolist()
print(l_1d)
# [0, 1, 2]
2次元の場合。
a_2d = np.arange(6).reshape((2, 3))
print(a_2d)
# [[0 1 2]
# [3 4 5]]
l_2d = a_2d.tolist()
print(l_2d)
# [[0, 1, 2], [3, 4, 5]]
3次元の場合。
a_3d = np.arange(24).reshape((2, 3, 4))
print(a_3d)
# [[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
#
# [[12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]]]
l_3d = a_3d.tolist()
print(l_3d)
# [[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]]
インデックス[n]
を繰り返すことで要素にアクセスできる。
print(l_3d[0])
# [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
print(l_3d[0][0])
# [0, 1, 2, 3]
print(l_3d[0][0][0])
# 0
なお、0次元(スカラー)の場合、リストではなく要素に応じたPythonの型(整数int
や浮動小数点数float
など)のオブジェクトになる。
a_0d = np.array(100)
print(a_0d)
# 100
print(type(a_0d))
# <class 'numpy.ndarray'>
i = a_0d.tolist()
print(i)
# 100
print(type(i))
# <class 'int'>