それぞれの利点と欠点は何ですか?
私が見た限りでは、必要に応じてどちらか一方を他方の代わりに使用できるので、両方を使用する必要があるのでしょうか、それともどちらか一方だけに固執するべきでしょうか?
プログラムのスタイルは選択に影響しますか? 私は NumPy を使用して機械学習を行っているため、確かに多くの行列がありますが、ベクトル (配列) もたくさんあります。
ベストアンサー1
Numpy行列は厳密に 2 次元ですが、Numpy配列(ndarray) は N 次元です。行列オブジェクトは ndarray のサブクラスなので、ndarray のすべての属性とメソッドを継承します。
NumPy 行列の主な利点は、行列の乗算に便利な表記法が提供されることです。つまり、a と b が行列の場合、 はa*b
それらの行列積です。
import numpy as np
a = np.mat('4 3; 2 1')
b = np.mat('1 2; 3 4')
print(a)
# [[4 3]
# [2 1]]
print(b)
# [[1 2]
# [3 4]]
print(a*b)
# [[13 20]
# [ 5 8]]
一方、Python 3.5 以降、NumPy は@
演算子を使用した中置行列乗算をサポートしているため、Python >= 3.5 では ndarray を使用した行列乗算と同じ利便性を実現できます。
import numpy as np
a = np.array([[4, 3], [2, 1]])
b = np.array([[1, 2], [3, 4]])
print(a@b)
# [[13 20]
# [ 5 8]]
行列オブジェクトと ndarray はどちらも.T
転置を返す必要がありますが、行列オブジェクト.H
には共役転置と.I
逆転置を返すものもあります。
対照的に、NumPy 配列は、演算が要素ごとに適用されるという規則に一貫して従います (new@
演算子を除く)。したがって、とa
がb
NumPy 配列の場合、a*b
配列は要素ごとにコンポーネントを乗算することによって形成されます。
c = np.array([[4, 3], [2, 1]])
d = np.array([[1, 2], [3, 4]])
print(c*d)
# [[4 6]
# [6 4]]
行列の乗算の結果を得るには、次のようにしますnp.dot
(または、@
Python >= 3.5 では上記のように)。
print(np.dot(c,d))
# [[13 20]
# [ 5 8]]
演算子**
の動作も異なります。
print(a**2)
# [[22 15]
# [10 7]]
print(c**2)
# [[16 9]
# [ 4 1]]
はa
行列なので、a**2
行列の積を返しますa*a
。c
は ndarray なので、c**2
各要素を要素ごとに 2 乗した ndarray を返します。
行列オブジェクトと ndarray の間には、他にも技術的な違いがあります (、項目の選択、シーケンスの動作に関係しますnp.ravel
)。
NumPy 配列の主な利点は、2 次元行列よりも汎用性が高いことです。3 次元配列が必要な場合はどうなるでしょうか。その場合は、行列オブジェクトではなく、ndarray を使用する必要があります。したがって、行列オブジェクトの使用方法を学ぶには、より多くの作業が必要になります。行列オブジェクトの操作と ndarray の操作を学習する必要があります。
行列と配列の両方を混在させたプログラムを書くと、乗算によって予期しない結果が返されないように、変数がどのタイプのオブジェクトであるかを追跡する必要があるため、作業が困難になります。
対照的に、ndarray のみを使用する場合は、関数や表記が若干異なることを除いて、行列オブジェクトで実行できるすべてのこと、さらにそれ以上のことを実行できます。
NumPy 行列積表記の見た目の魅力をあきらめてもよいのであれば (Python >= 3.5 では ndarrays でほぼ同じようにエレガントに実現できます)、NumPy 配列が間違いなく最適だと思います。
np.asmatrix
PS. もちろん、 と を使用すると、一方を他方に変換できるためnp.asarray
(配列が 2 次元である限り)、どちらか一方を犠牲にして他方を選択する必要はありません。
arrays
NumPyとNumPy matrix
esの違いの概要がありますここ。