2016-06-21 18 views
3

通常、newaxisをどこに挿入すべきかを知ったら、a[:, np.newaxis,...]を実行できます。特定の軸に新生軸を挿入する良い方法はありますか?NumPy配列の可変位置にnewaxisを挿入する

ここで私はどのようにそれを行うのですか?私はこれよりも、いくつかの非常に良い方法がなければならないと思う:

def addNewAxisAt(x, axis): 
    _s = list(x.shape) 
    _s.insert(axis, 1) 
    return x.reshape(tuple(_s)) 

def addNewAxisAt2(x, axis): 
    ind = [slice(None)]*x.ndim 
    ind.insert(axis, np.newaxis) 
    return x[ind] 

答えて

1

np.insertは、それがスライスのリストを作成し、1つまたは複数の要素を変更するあなたのよう

slobj = [slice(None)]*ndim 
... 
slobj[axis] = slice(None, index) 
... 
new[slobj] = arr[slobj2] 

を行います。

apply_along_axisアレイを構築し、そして割り出しタプルに

outarr[tuple(i.tolist())] = res 

他numpyの機能を変換するだけでなく、このように動作します。

私の提案は、最初のリストをNoneを保持するのに十分な大きさにすることです。その後、私はinsertを使用する必要はありません。

In [1076]: x=np.ones((3,2,4),int) 

In [1077]: ind=[slice(None)]*(x.ndim+1) 

In [1078]: ind[2]=None 

In [1080]: x[ind].shape 
Out[1080]: (3, 2, 1, 4) 

In [1081]: x[tuple(ind)].shape # sometimes converting a list to tuple is wise 
Out[1081]: (3, 2, 1, 4) 

が判明np.expand_dims

In [1090]: np.expand_dims(x,2).shape 
Out[1090]: (3, 2, 1, 4) 

があるそれはあなたがやるようreshapeを使用しますが、タプル連結して新しい形状を作成します。

def expand_dims(a, axis): 
    a = asarray(a) 
    shape = a.shape 
    if axis < 0: 
     axis = axis + len(shape) + 1 
    return a.reshape(shape[:axis] + (1,) + shape[axis:]) 

タイミングはどちらが良いかについて私にはあまり教えてくれません。これらは2μsの範囲です。関数のコードを単にラップするだけで差が生じます。

3

シングルトン次元(dim length = 1)np.insertで元アレイ状に形状基準として追加され、これを直接、その形状を変更することができることを、とても似 -

x.shape = np.insert(x.shape,axis,1) 

まあ、我々としても、これはそうのように、np.diffのビットとnp.cumsumトリックで複数の新しい軸を招待するために拡張するかもしれない -

insert_idx = (np.diff(np.append(0,axis))-1).cumsum()+1 
x.shape = np.insert(x.shape,insert_idx,1) 

サンプルの実行 - 限り私はちょうどようになる4位に入れるために、タプルのインデックスと省略記号のオブジェクトたとえば

を使用することができますを言うことができるように

In [151]: def addNewAxisAt(x, axis): 
    ...:  insert_idx = (np.diff(np.append(0,axis))-1).cumsum()+1 
    ...:  x.shape = np.insert(x.shape,insert_idx,1) 
    ...:  

In [152]: A = np.random.rand(4,5) 

In [153]: addNewAxisAt(A, axis=1) 

In [154]: A.shape 
Out[154]: (4, 1, 5) 

In [155]: A = np.random.rand(5,6,8,9,4,2) 

In [156]: addNewAxisAt(A, axis=5) 

In [157]: A.shape 
Out[157]: (5, 6, 8, 9, 4, 1, 2) 

In [158]: A = np.random.rand(5,6,8,9,4,2,6,7) 

In [159]: addNewAxisAt(A, axis=(1,3,4,6)) 

In [160]: A.shape 
Out[160]: (5, 1, 6, 1, 1, 8, 1, 9, 4, 2, 6, 7) 
+0

もちろん、ああ! ndarrayの形状が設定可能なプロパティであることを忘れるのはとても簡単です – wim

+0

numpy.reshapeもあります。これは非突然変異的なやり方でこれを行うことができます。 – user2357112

+0

@ user2357112よろしく!コードから 'np.insert'によって出力された新しい形状情報を使用することによって。 – Divakar

0

>>> a = np.ones((3,3,3,3,3,3,3)) 
>>> a.shape 
(3, 3, 3, 3, 3, 3, 3) 
>>> t = tuple([slice(None)]*4 + [np.newaxis, Ellipsis]) 
>>> a[t].shape 
(3, 3, 3, 3, 1, 3, 3, 3) 

編集:私の解決策はラメです。answer from Divakarが好きです。

関連する問題