web-dev-qa-db-ja.com

numpy配列と行列の違いは何ですか?どちらを使用すればよいですか?

それぞれの長所と短所は何ですか?

私が見てきたことから、どちらかが必要に応じて他方の代わりとして機能することができますので、両方を使用する必要がありますか、どちらか一方だけに固執する必要がありますか?

プログラムのスタイルは私の選択に影響しますか?私はnumpyを使用していくつかの機械学習を行っていますので、実際には多くの行列がありますが、ベクトル(配列)もたくさんあります。

300
levesque

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でndarraysを使用した行列乗算と同じ便利さを実現できます。

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配列は、操作が要素ごとに適用されるという規則を一貫して順守します(新しい@演算子を除く)。したがって、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の操作を学習する必要があります。

行列と配列の両方を使用するプログラムを作成すると、変数がどのタイプのオブジェクトであるかを追跡する必要があり、乗算が予期しないものを返すことがないため、人生が困難になります。

対照的に、ndarraysのみに固執する場合、マトリックスオブジェクトが実行できることはすべて実行できますが、わずかに異なる関数/表記法を除きます。

NumPy行列積表記法(Python> = 3.5のndarraysとほぼ同じくらい上品に達成できる)の視覚的な魅力を放棄したい場合は、NumPy配列が間違いなく進むべき方法だと思います。

PS。もちろん、np.asmatrixnp.asarrayを使用すると、(配列が2次元である限り)相互に変換できるため、実際に一方を選択する必要はありません。


NumPy arraysとNumPy matrixes here の違いの概要があります。

355
unutbu

Scipy.orgは、配列の使用を推奨しています:

* 'array'または 'matrix'?どちらを使うべきですか? -短い答え

配列を使用します。

  • それらは、numpyの標準のベクトル/行列/テンソルタイプです。多くのnumpy関数は、行列ではなく配列を返します。

  • 要素ごとの演算と線形代数の演算には明確な違いがあります。

  • 必要に応じて、標準ベクトルまたは行/列ベクトルを使用できます。

配列型を使用する唯一の欠点は、*の代わりにdotを使用して、2つのテンソルを乗算(削減)する必要があることです(スカラー積、行列ベクトル乗算など)。

83
atomh33ls

Unutbuのリストに1つのケースを追加するだけです。

Numpy行列またはmatlabのような行列言語と比較したnumpy ndarraysの最大の実用的な違いの1つは、reduce操作で次元が保持されないことです。行列は常に2次元ですが、たとえば配列の平均は1次元少なくなります。

たとえば、行列または配列の行を意味します:

マトリックスあり

>>> m = np.mat([[1,2],[2,3]])
>>> m
matrix([[1, 2],
        [2, 3]])
>>> mm = m.mean(1)
>>> mm
matrix([[ 1.5],
        [ 2.5]])
>>> mm.shape
(2, 1)
>>> m - mm
matrix([[-0.5,  0.5],
        [-0.5,  0.5]])

配列あり

>>> a = np.array([[1,2],[2,3]])
>>> a
array([[1, 2],
       [2, 3]])
>>> am = a.mean(1)
>>> am.shape
(2,)
>>> am
array([ 1.5,  2.5])
>>> a - am #wrong
array([[-0.5, -0.5],
       [ 0.5,  0.5]])
>>> a - am[:, np.newaxis]  #right
array([[-0.5,  0.5],
       [-0.5,  0.5]])

また、配列と行列を混在させると、多くの「楽しい」デバッグ時間が発生すると思います。ただし、scipy.sparse行列は、乗算などの演算子に関しては常に行列です。

27
Josef

他の人が言及したように、おそらくmatrixの主な利点は、行列乗算に便利な表記法を提供することでした。

ただし、 Python 3.5では、最終的に行列乗算専用の挿入演算子があります@

最新のNumPyバージョンでは、ndarraysで使用できます。

A = numpy.ones((1, 3))
B = numpy.ones((3, 3))
A @ B

そのため、最近ではさらに疑わしい場合は、ndarrayに固執する必要があります。

18
Peque