回答:
>>> test[:,0]
array([1, 3, 5])
同様に、
>>> test[1,:]
array([3, 4])
行にアクセスできます。これについては、NumPyリファレンスのセクション1.4(インデックス)で説明しています。これは、少なくとも私の経験では速いです。ループ内の各要素にアクセスするよりもはるかに高速です。
また、一度に複数の列にアクセスする場合は、次のようにします。
>>> test = np.arange(9).reshape((3,3))
>>> test
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> test[:,[0,2]]
array([[0, 2],
[3, 5],
[6, 8]])
test[:,[0,2]]
データにアクセスするだけです。たとえば、test[:, [0,2]] = something
テストを変更し、別の配列を作成しません。しかしcopy_test = test[:, [0,2]]
、実際にはあなたが言うようにコピーを作成します。
test[:,[0,2]]
データにアクセスするのにアクセスtest[:, [0, 2]][:, [0, 1]]
しないのですか?同じことをもう一度行うと結果が異なることは非常に直感的ではないようです。
>>> test[:,0]
array([1, 3, 5])
このコマンドは、行ベクトルを提供します。ループするだけの場合は問題ありませんが、3xNの次元を持つ他の配列とhstackする場合は、
ValueError: all the input arrays must have same number of dimensions
ながら
>>> test[:,[0]]
array([[1],
[3],
[5]])
列ベクトルを提供するため、連結またはhstack操作を実行できます。
例えば
>>> np.hstack((test, test[:,[0]]))
array([[1, 2, 1],
[3, 4, 3],
[5, 6, 5]])
質問への回答はありますが、いくつかのニュアンスについて触れさせてください。
配列の最初の列に興味があるとしましょう
arr = numpy.array([[1, 2],
[3, 4],
[5, 6]])
他の回答からすでに知っているように、「行ベクトル」(形状の配列(3,)
)の形式で取得するには、スライスを使用します。
arr_c1_ref = arr[:, 1] # creates a reference to the 1st column of the arr
arr_c1_copy = arr[:, 1].copy() # creates a copy of the 1st column of the arr
配列がビューであるか別の配列のコピーであるかを確認するには、次のようにします。
arr_c1_ref.base is arr # True
arr_c1_copy.base is arr # False
ndarray.baseを参照してください。
2つの間の明らかな違い(変更arr_c1_ref
はに影響しますarr
)に加えて、それぞれを走査するためのバイトステップ数は異なります。
arr_c1_ref.strides[0] # 8 bytes
arr_c1_copy.strides[0] # 4 bytes
ストライドを参照してください。何でこれが大切ですか?あなたがのA
代わりに非常に大きな配列を持っていると想像してくださいarr
:
A = np.random.randint(2, size=(10000,10000), dtype='int32')
A_c1_ref = A[:, 1]
A_c1_copy = A[:, 1].copy()
そして、あなたは最初の列のすべての要素の合計を計算したい、すなわち、A_c1_ref.sum()
またはA_c1_copy.sum()
。コピーしたバージョンを使用すると、はるかに高速になります。
%timeit A_c1_ref.sum() # ~248 µs
%timeit A_c1_copy.sum() # ~12.8 µs
これは、前述のストライドの数が異なるためです。
A_c1_ref.strides[0] # 40000 bytes
A_c1_copy.strides[0] # 4 bytes
カラムコピーを使用する方が良いように見えるかもしれませんが、コピーの作成には時間がかかり、より多くのメモリを使用するという理由から、常にそうであるとは限りません(この場合、作成に約200 µsかかりました A_c1_copy
)。ただし、最初にコピーが必要な場合、または配列の特定の列に対して多くの異なる操作を実行する必要があり、速度を上げるためにメモリを犠牲にしても問題ない場合は、コピーを作成する方法です。
主に列を操作することに関心がある場合は、行優先( 'C')順(デフォルト)ではなく、列優先( 'F')順に配列を作成することをお勧めします。 )、前と同じようにスライスして、コピーせずに列を取得します。
A = np.asfortranarray(A) # or np.array(A, order='F')
A_c1_ref = A[:, 1]
A_c1_ref.strides[0] # 4 bytes
%timeit A_c1_ref.sum() # ~12.6 µs vs ~248 µs
これで、列ビューで合計操作(またはその他の操作)を実行する方がはるかに高速になりました。
最後に、配列を転置して行スライスを使用することは、元の配列で列スライスを使用することと同じです。転置は、元の配列の形状とストライドを交換するだけで行われるためです。
A.T[1,:].strides[0] # 40000