web-dev-qa-db-ja.com

Numpyが1列の1dから2d配列に変形します

numpyでは、結果の配列の次元は実行時に異なります。多くの場合、1次元配列と1列の2次元配列の間で混乱が生じます。ある場合には、列を反復処理できますが、別の場合にはできません。

その問題をエレガントにどのように解決しますか?次元をチェックするifステートメントでコードを散らかすことを避けるために、この関数を使用します。

def reshape_to_vect(ar):
    if len(ar.shape) == 1:
      return ar.reshape(ar.shape[0],1)
    return ar

ただし、これは上品でコストがかかります。より良い解決策はありますか?

17
DevShark

最も簡単な方法:

ar.reshape(-1, 1)
18
KaaPex

あなたができる-

ar.reshape(ar.shape[0],-1)

reshapeへの2番目の入力:-1は、2番目の軸の要素数を処理します。したがって、2D入力の場合、変更はありません。 1D入力の場合、2Dが要素の合計数であるため、すべての要素が最初の軸に「プッシュ」されるar.shape[0]配列を作成します。

サンプルの実行

1Dケース:

In [87]: ar
Out[87]: array([ 0.80203158,  0.25762844,  0.67039516,  0.31021513,  0.80701097])

In [88]: ar.reshape(ar.shape[0],-1)
Out[88]: 
array([[ 0.80203158],
       [ 0.25762844],
       [ 0.67039516],
       [ 0.31021513],
       [ 0.80701097]])

2Dケース:

In [82]: ar
Out[82]: 
array([[ 0.37684126,  0.16973899,  0.82157815,  0.38958523],
       [ 0.39728524,  0.03952238,  0.04153052,  0.82009233],
       [ 0.38748174,  0.51377738,  0.40365096,  0.74823535]])

In [83]: ar.reshape(ar.shape[0],-1)
Out[83]: 
array([[ 0.37684126,  0.16973899,  0.82157815,  0.38958523],
       [ 0.39728524,  0.03952238,  0.04153052,  0.82009233],
       [ 0.38748174,  0.51377738,  0.40365096,  0.74823535]])
9
Divakar

Divakarによる回答のバリエーションはx = np.reshape(x, (len(x),-1))です。これは、入力が1dまたは2dリストの場合も処理します。

3
Luca Citi

そもそも形状を変更する必要を回避するために、リストで行/列をスライスする場合、または「実行中の」スライスで、1行/列の2D配列を取得します

import numpy as np
x = np.array(np.random.normal(size=(4,4)))
print x, '\n'

Result:
[[ 0.01360395  1.12130368  0.95429414  0.56827029]
 [-0.66592215  1.04852182  0.20588886  0.37623406]
 [ 0.9440652   0.69157556  0.8252977  -0.53993904]
 [ 0.6437994   0.32704783  0.52523173  0.8320762 ]] 

y = x[:,[0]]
print y, 'col vector \n'
Result:
[[ 0.01360395]
 [-0.66592215]
 [ 0.9440652 ]
 [ 0.6437994 ]] col vector 


y = x[[0],:]
print y, 'row vector \n'

Result:
[[ 0.01360395  1.12130368  0.95429414  0.56827029]] row vector 

# Slice with "running" index on a column
y = x[:,0:1]
print y, '\n'

Result:
[[ 0.01360395]
 [-0.66592215]
 [ 0.9440652 ]
 [ 0.6437994 ]] 

代わりに、行/列の選択に単一の数値を使用すると、1D配列が発生します。これが問題の根本原因です。

y = x[:,0]
print y, '\n'

Result:
[ 0.01360395 -0.66592215  0.9440652   0.6437994 ] 
1
Yuval Atzmon

あなたの例は不可解であるため、dtypeについて尋ねました。

3つの要素(1d)と3つのフィールドを持つ構造化配列を作成できます。

_In [1]: A = np.ones((3,), dtype='i,i,i')
In [2]: A
Out[2]: 
array([(1, 1, 1), (1, 1, 1), (1, 1, 1)], 
      dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])
_

名前で1つのフィールドにアクセスできます(括弧を追加しても変更はありません)

_In [3]: A['f0'].shape
Out[3]: (3,)
_

しかし、2つのフィールドにアクセスすると、まだ1D配列が得られます

_In [4]: A[['f0','f1']].shape
Out[4]: (3,)
In [5]: A[['f0','f1']]
Out[5]: 
array([(1, 1), (1, 1), (1, 1)], 
      dtype=[('f0', '<i4'), ('f1', '<i4')])
_

実際に値を見ると、これらの余分な括弧は重要です

_In [22]: A['f0']
Out[22]: array([1, 1, 1], dtype=int32)
In [23]: A[['f0']]
Out[23]: 
array([(1,), (1,), (1,)], 
      dtype=[('f0', '<i4')])
_

配列が単純な2D配列の場合、まだ形状がわかりません

_In [24]: A=np.ones((3,3),int)
In [25]: A[0].shape
Out[25]: (3,)
In [26]: A[[0]].shape
Out[26]: (1, 3)
In [27]: A[[0,1]].shape
Out[27]: (2, 3)
_

しかし、配列が2dであることを確認するという質問については、インデックスが1dまたは2を返すかどうかに関係なく、あなたの関数は基本的に大丈夫です

_def reshape_to_vect(ar):
    if len(ar.shape) == 1:
      return ar.reshape(ar.shape[0],1)
    return ar
_

len(ar.shape)の代わりに_ar.ndim_をテストできます。しかし、いずれにせよ、コストはかかりません-つまり、実行時間は最小限です-大きな配列操作はありません。 reshapeはデータをコピーしません(ストライドが奇妙でない限り)ので、共有データポインターで新しい配列オブジェクトを作成するだけのコストです。

_np.atleast_2d_;のコードを見てください。 0dと1dをテストします。 1dの場合、_result = ary[newaxis,:]_を返します。余分な軸が最初に追加され、軸を追加するためのより自然なnumpy位置が追加されます。最後に追加します。

ar.reshape(ar.shape[0],-1)は、ifテストをバイパスする賢い方法です。小規模なタイミングテストではより高速になりますが、関数呼び出し層の影響であるマイクロ秒について説明しています。

_np.column_stack_は、必要に応じて列配列を作成する別の関数です。それは使用しています:

_ if arr.ndim < 2:
        arr = array(arr, copy=False, subok=True, ndmin=2).T
_
0
hpaulj
y = np.array(12)
y = y.reshape(-1,1)
print(y.shape)

O/P:- (1, 1)
0
Murtaza Chawala