2016-10-05 21 views
3

データ型intの形状(M、N、P)データタイプobjectの形状(N、P)の2D配列を取得し、これを妥当な効率で実行したいと考えています。(N、P)形状の2次元オブジェクト配列への形状(M、N、P)配列によるnumpy int配列の効率的な変換

tuplelistまたはnumpy.ndarrayのいずれかのオブジェクトに満足しています。

私はリストを経由しなければならない解決策のハックを持っています。 a2[(x, y)] == (x, y)

それはmを転置してa2を作ることが可能であったはずのように感じている性質を持って、この例では、

import numpy as np 

m = np.mgrid[:8, :12] 

l = zip(*(v.ravel() for v in m)) 
a2 = np.empty(m.shape[1:], dtype=np.object) 
a2.ravel()[:] = l 

最終配列a2必要があります。だから、私は何かが欠けてるように感じていますこのような:

a2 = m.transpose(1,2,0).astype(np.object).reshape(m.shape[1:])

numpyのため、実際のcre代わりに、オブジェクトの内部で何を気にしたりしません。そこにどうあるべきか、多くの次元伝えることができるタイプnp.objectのnumpyのアレイをating:

a2 = np.array(m.transpose(1,2,0), astype=object, ndim=2) 

numpyのは、彼らが三次元で異なる形状を持っている場合は、この例では(ネストされた反復可能オブジェクトの最終深さの前に停止することを知っています)、mには不規則性がないので不可能と思われます。

またはa2を作成し、転置とそれを埋める:例えばこの場合

a2 = np.empty(m.shape[1:], dtype=np.object) 
a2[...] = m.transpose(1, 2, 0) 

m.transpose(1, 2, 0)[2, 4]np.array([2, 4])であり、それをa2[2, 4]に割り当てることは完全に合法であったであろう。しかし、これらの3つのより合理的な試みはどれも機能しません。 m小さいため

答えて

1

だから:

In [513]: m = np.mgrid[:3,:4] 
In [514]: m.shape 
Out[514]: (2, 3, 4) 
In [515]: m 
Out[515]: 
array([[[0, 0, 0, 0], 
     [1, 1, 1, 1], 
     [2, 2, 2, 2]], 

     [[0, 1, 2, 3], 
     [0, 1, 2, 3], 
     [0, 1, 2, 3]]]) 
In [516]: ll = list(zip(*(v.ravel() for v in m))) 
In [517]: ll 
Out[517]: 
[(0, 0), 
(0, 1), 
(0, 2), 
... 
(2, 3)] 
In [518]: a2=np.empty(m.shape[1:], dtype=object) 
In [519]: a2.ravel()[:] = ll 
In [520]: a2 
Out[520]: 
array([[(0, 0), (0, 1), (0, 2), (0, 3)], 
     [(1, 0), (1, 1), (1, 2), (1, 3)], 
     [(2, 0), (2, 1), (2, 2), (2, 3)]], dtype=object) 

右形状の空きを作る、そして[:]=介して充填は、アレイのobject深さを制御するための最良の方法です。 np.array(...)はデフォルトで可能な限り高い次元になります。この場合は3dになります。

したがって、主な質問は、そのllタプルのリストを構築する良い方法があるということです。

a2.ravel()[:] = np.array(ll) 

は、(12,2) into shape (12)と不平を言います。 、

In [533]: a2.ravel()[:] = np.array(ll).tolist() 
In [534]: a2 
Out[534]: 
array([[[0, 0], [0, 1], [0, 2], [0, 3]], 
     [[1, 0], [1, 1], [1, 2], [1, 3]], 
     [[2, 0], [2, 1], [2, 2], [2, 3]]], dtype=object) 

m形状がある(2:

は私がllのような配列で開始した場合、後方の作業、ネストされたリストにそれを回す、a2の要素を除いて割り当て作品は、ないタプルのリストです3,4)and np.array(ll)shape is (12,2), then m.reshape(2、-1).T`は同じことを生成します。

a2.ravel()[:] = m.reshape(2,-1).T.tolist() 

私は最初に転位してから再成形した可能性があります。m.transpose(1,2,0).reshape(-1,2)

は、私が理解を通じて形状を変更する配列を渡す必要があるタプルを取得するには、次の

a2.ravel()[:] = [tuple(l) for l in m.reshape(2,-1).T] 

===============

m.transpose(1,2,0).astype(object)まだ3Dです。整数へのポインタで整数を変更しただけです。配列の次元とdtypeの間には「壁」があります。変形や転置のようなものは、寸法にしか作用せず、その壁を貫通したり移動したりしないでください。リストはすべての方法でポインタです。オブジェクト配列はポインタをdtypeレベルでのみ使用します。

a2.ravel()[:]=の表現を恐れてはいけません。 ravelは安価な形をしており、配列のフラット化されたバージョンへの代入は実際には2dバージョンへの代入より高速かもしれません。結局のところ、データ(この場合はポインタ)はフラットデータバッファに格納されます。

(ちょっと遊んだ後で)私はラブや改造なしで割り当てを行うことができます(まだobject境界を移動するにはtolistが必要です)。リストのネストはa2の形状を「オブジェクト」レベルに合わせる必要があります。

a2[...] = m.transpose(1,2,0).tolist() # even a2[:] works 

(これはnp.arraymaxdimパラメータを与えることについての議論を思い起こさせる - Prevent numpy from creating a multidimensional array)。

tolistの使用は非効率的なようです。しかし、a2の要素がタプル(またはタプルへのポインタ)である場合、それらのタプルは何らかの方法で作成されなければなりません。 mcデータバッファは、1組のタプルとして見ることはできません。そのようなオブジェクトを作成する最も効率的な方法は、tolist(理解度が[tuple...])である可能性があります。

==============

は私が右の数字を2つの素子アレイを生成する、転置インデックスを作成できることに注意していましたか?

In [592]: m.transpose(1,2,0)[1,2] 
Out[592]: array([1, 2]) 
In [593]: m.transpose(1,2,0)[0,1] 
Out[593]: array([0, 1]) 

==================

構造化された配列のためtolistはタプルを使用しているので、私は何ができる:

In [598]: a2[:]=m.transpose(1,2,0).copy().view('i,i').reshape(a2.shape).tolist() 

In [599]: a2 
Out[599]: 
array([[(0, 0), (0, 1), (0, 2), (0, 3)], 
     [(1, 0), (1, 1), (1, 2), (1, 3)], 
     [(2, 0), (2, 1), (2, 2), (2, 3)]], dtype=object) 

リストの理解を避けることができます。それは必ずしも簡単ではない。

関連する問題