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


345

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

私が見てきたことから、必要に応じてどちらか一方をもう一方の代わりとして機能させることができるので、両方を使用するか、どちらか一方のみを使用する必要がありますか?

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


3
答えを正当化するのに十分な情報はありませんが、主な違いは、乗算の実装にあります。行列は行列/テンソル乗算を実行しますが、配列は要素ごとの乗算を実行します。
Mike Axiak、2011

5
Python 3.5は、行列の乗算(PEP 465)のためにinfix @演算子を追加し、NumPy 1.10はそのサポートを追加しました。あなたは、Python 3.5+とnumpyの1.10+を使用しているのであれば、あなたはただ書くことができるA @ B代わりにA.dot(B)、どこAB2Dあるndarrayの。これにより、matrixプレーンndarrayの代わりにIMHO を使用する主な利点が取り除かれます。
MiniQuark、2016

回答:



396

numpyの行列は numpyのながら、厳密に2次元である配列(ndarrays)はN次元です。Matrixオブジェクトは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 @演算子を除く)に従います。したがって、abnumpy配列の場合、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。ためcndarrayあり、c**2各成分の二乗要素単位でndarrayを返します。

マトリックスオブジェクトとndarrayの間には、他にも技術的な違いがあります(np.ravel、項目の選択、シーケンスの動作に関係しています)。

numpy配列の主な利点は、2次元行列よりも一般的であることです。3次元配列が必要な場合はどうなりますか?次に、行列オブジェクトではなく、ndarrayを使用する必要があります。したがって、行列オブジェクトの使用法を学ぶことはより手間がかかります。行列オブジェクトの操作とndarray操作を学ぶ必要があります。

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

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

NumPy行列の製品表記法(Python> = 3.5のndarraysでほぼエレガントに実現できる)の視覚的な魅力を放棄するつもりなら、NumPy配列は間違いなく進むべき道だと思います。

PS。もちろん、あなたが本当に以来、他を犠牲にしていずれかを選択する必要はありませんnp.asmatrixし、np.asarray(配列が2次元である限り)あなたは一方を他方に変換することができます。


numpyの間の相違点の概要があるarraysnumpyのの対matrixES ここでは


7
不思議に思う人のmat**nために、行列は次のようにして配列にエレガントに適用できますreduce(np.dot, [arr]*n)
askewchan

6
または単にnp.linalg.matrix_power(mat, n)
エリック

行列が高速になるかどうか疑問に思っています... ndarrayよりも少ないチェックを実行する必要があると思います。
PascalVKooten 2017

1
実際、timeitテストでは、などnp.dot(array2, array2)より高速なndarray操作が示されていますmatrix1*matrix2matrixはのような特別なメソッドをオーバーライドするndarrayのサブクラスであるため、これは理にかなっています__mul__matrix.__mul__を呼び出しますnp.dot。したがって、ここにはコードの再利用があります。使用matrix*matrixするチェックを少なくする代わりに、追加の関数呼び出しが必要です。したがって、使用する利点matrixは純粋に構文上のものであり、パフォーマンスは向上しません。
unutbu 2017

4 * 1 + 3 * 3は、np.dot(c、d)を実行したときに13になります。これは、実際には数学のクロス積と呼ばれていません
PirateApp

92

Scipy.orgは配列を使用することをお勧めします:

*「配列」または「行列」?どちらを使用すればよいですか?- 簡潔な答え

配列を使用します。

  • これらは、numpyの標準のベクトル/マトリックス/テンソル型です。多くのnumpy関数は、行列ではなく配列を返します。

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

  • 必要に応じて、標準ベクトルまたは行/列ベクトルを持つことができます。

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


11
受け入れられた答えはより多くの情報を提供しますが、実際の答えは確かに固執しndarrayます。使用の主な引数はmatrix、コードが線形代数で重く、dot関数へのすべての呼び出しで不明瞭に見える場合です。しかし、この議論は見、今@演算子は、マトリックス乗算で使用するために受け入れられていること、将来的に消えますPEP 465。これにはPython 3.5と最新バージョンのNumpyが必要です。行列クラスは...そう、より良い新しいコードをndarray使用するには、遠い将来に廃止される可能性がある
バSwinckels

6
そのページはscipy.sparseマトリックスについて丁寧に忘れています。コードで密行列と疎行列の両方を使用すると、に固執するのがはるかに簡単になりmatrixます。
David Nemeskey

3
私の意見では、配列の主な欠点は、列のスライスによってフラットな配列が返されることです。これは、numpy配列を基本的にスパース行列と自由に交換できる一方で、numpy配列をscipy.sparse行列と同じ方法で処理できないという重要な欠点にもつながります。このコンテキストでは、scipyが配列の使用を推奨し、互換性のある疎配列を提供しないという不合理な種類です。
ラジコン、

29

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

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

たとえば、行列または配列のdemean行:

マトリックス付き

>>> 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行列は、乗算などの演算子に関しては常に行列です。


20

他の人が述べたように、おそらくの主な利点はmatrix、行列の乗算に便利な表記法が提供されたことです。

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

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

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

したがって、最近では、さらに疑問がある場合はに固執する必要がありndarrayます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.