Pythonで行ベクトルと列ベクトルを区別する良い方法はありますか?これまでのところ、私はnumpyとscipyを使用していますが、これまで見てきたことは、ベクトルを与えるとしたら、
from numpy import *
Vector = array([1,2,3])
彼らは天気を言うことができません。私は行または列ベクトルを意味します。さらに:
array([1,2,3]) == array([1,2,3]).transpose()
True
これは「現実の世界」では単に真実ではありません。上記のモジュールからのベクトル上の関数のほとんどは、区別する必要がないことを理解しています。たとえば、outer(a,b)
またはa.dot(b)
ですが、自分の都合で区別したいと思います。
配列に別の次元を追加することにより、区別を明示的にすることができます。
>>> a = np.array([1, 2, 3])
>>> a
array([1, 2, 3])
>>> a.transpose()
array([1, 2, 3])
>>> a.dot(a.transpose())
14
ここで強制的に列ベクトルにします。
>>> a.shape = (3,1)
>>> a
array([[1],
[2],
[3]])
>>> a.transpose()
array([[1, 2, 3]])
>>> a.dot(a.transpose())
array([[1, 2, 3],
[2, 4, 6],
[3, 6, 9]])
別のオプションは、区別したいときにnp.newaxisを使用することです。
>>> a = np.array([1, 2, 3])
>>> a
array([1, 2, 3])
>>> a[:, np.newaxis]
array([[1],
[2],
[3]])
>>> a[np.newaxis, :]
array([[1, 2, 3]])
ベクターを書くときは、ダブル[]
を使用します。
次に、行ベクトルが必要な場合:
row_vector = array([[1, 2, 3]]) # shape (1, 3)
または、列ベクトルが必要な場合:
col_vector = array([[1, 2, 3]]).T # shape (3, 1)
Numpy.arrayのndminオプションを使用できると思います。 2に維持すると、それは(4,1)になり、転置は(1,4)になります。
>>> a = np.array([12, 3, 4, 5], ndmin=2)
>>> print a.shape
>>> (1,4)
>>> print a.T.shape
>>> (4,1)
作成するベクトルは行でも列でもないです。実際には1次元のみです。それを確認するには
myvector.ndim
は1
ですmyvector.shape
である(3,)
(1つの要素のみを持つタプル)を確認します。行ベクトルの場合は(1, 3)
、列の場合は(3, 1)
これを処理する2つの方法
reshape
現在のもの行または列を明示的に作成できます
row = np.array([ # one row with 3 elements
[1, 2, 3]
]
column = np.array([ # 3 rows, with 1 element each
[1],
[2],
[3]
])
または、ショートカット付き
row = np.r_['r', [1,2,3]] # shape: (1, 3)
column = np.r_['c', [1,2,3]] # shape: (3,1)
または、行の場合は(1, n)
、列の場合は(n, 1)
に変更できます
row = my_vector.reshape(1, -1)
column = my_vector.reshape(-1, 1)
-1
はn
の値を自動的に見つけます。
このケースでディスティクションが必要な場合は、代わりにmatrix
を使用することをお勧めします。ここで、
matrix([1,2,3]) == matrix([1,2,3]).transpose()
与える:
matrix([[ True, False, False],
[False, True, False],
[False, False, True]], dtype=bool)
ndarray
を使用して、2番目のディメンションを明示的に追加することもできます。
array([1,2,3])[None,:]
#array([[1, 2, 3]])
そして:
array([1,2,3])[:,None]
#array([[1],
# [2],
# [3]])
1x3アレイまたは3x1アレイが必要な場合:
import numpy as np
row_arr = np.array([1,2,3]).reshape((1,3))
col_arr = np.array([1,2,3]).reshape((3,1)))
作業を確認します。
row_arr.shape #returns (1,3)
col_arr.shape #returns (3,1)
ここで多くの答えが役立つことがわかりましたが、私には複雑すぎます。実際には、shape
とreshape
に戻りますが、コードは読みやすく、非常にシンプルで明示的です。
コンテキストで使用しない限り、PythonのNumpyはそれを区別しないようです。
「必要に応じて、標準ベクトルまたは行/列ベクトルを使用できます。」
":)ランク1配列を行ベクトルまたは列ベクトルとして扱うことができます。dot(A、v)はvを列ベクトルとして扱い、dot(v、A)はvを行ベクトルとして扱います。これにより、多数の転置を入力します。」
また、コード固有:「ランク1配列の転置は何もしません。」ソース: http://wiki.scipy.org/NumPy_for_Matlab_Users
次のように、配列の要素を行または列に保存できます。
>>> a = np.array([1, 2, 3])[:, None] # stores in rows
>>> a
array([[1],
[2],
[3]])
>>> b = np.array([1, 2, 3])[None, :] # stores in columns
>>> b
array([[1, 2, 3]])
別の直観的な方法を次に示します。次のものがあると仮定します。
>>> a = np.array([1, 3, 4])
>>> a
array([1, 3, 4])
最初に、それを唯一の行として2D配列を作成します。
>>> a = np.array([a])
>>> a
array([[1, 3, 4]])
その後、転置できます。
>>> a.T
array([[1],
[3],
[4]])
Numpyを使用してw^T * x
を計算しようとしたとき、非常に混乱しました。実際、自分で実装することはできませんでした。そのため、これはNumPyで知っておく必要がある数少ない落とし穴の1つです。
1D arrayに関する限り、行ベクトルと列ベクトルの区別なしがあります。それらはまったく同じです。
次の例を見てください。すべての場合で同じ結果が得られますが、(理論上の)線形代数では当てはまりません。
In [37]: w
Out[37]: array([0, 1, 2, 3, 4])
In [38]: x
Out[38]: array([1, 2, 3, 4, 5])
In [39]: np.dot(w, x)
Out[39]: 40
In [40]: np.dot(w.transpose(), x)
Out[40]: 40
In [41]: np.dot(w.transpose(), x.transpose())
Out[41]: 40
In [42]: np.dot(w, x.transpose())
Out[42]: 40
その情報を使用して、ベクトル|w|^2
の長さの2乗を計算してみましょう。
このために、w
を2D配列に変換する必要があります。
In [51]: wt = w[:, np.newaxis]
In [52]: wt
Out[52]:
array([[0],
[1],
[2],
[3],
[4]])
次に、ベクトルw
の長さの2乗(または大きさの2乗)を計算しましょう。
In [53]: np.dot(w, wt)
Out[53]: array([30])
w
、wt
の代わりにwt
、w
を使用したことに注意してください(理論上の線形代数のように)np.dot(wt、w )。したがって、ベクトルの長さの2乗は[30]
になります。多分これは(numpyの解釈の)行ベクトルと列ベクトルを区別する方法の1つですか?
そして最後に、w^T * x
を実装する方法を見つけたことに言及しましたか?はい、私はやった:
In [58]: wt
Out[58]:
array([[0],
[1],
[2],
[3],
[4]])
In [59]: x
Out[59]: array([1, 2, 3, 4, 5])
In [60]: np.dot(x, wt)
Out[60]: array([40])
したがって、NumPyでは、上記のように、オペランドの順序が逆になります。これは、理論上の線形代数で調べたものとは異なります。
P.S。: numpyの潜在的な落とし穴
優れた Pandas ライブラリは、numpyにこれらの種類の操作をより直感的なIMOにする機能を追加します。例えば:
import numpy as np
import pandas as pd
# column
df = pd.DataFrame([1,2,3])
# row
df2 = pd.DataFrame([[1,2,3]])