2017-12-14 24 views
0

私はPython 3.6とnumpyを使用しています。Python/numpyの配列分割

hdf5ファイルから、私は2D配列であるテーブルの列を読みました。

配列の各行は、有限要素のノードのIDを保持します。

テーブルは、同じテーブル内の両方の下や高次要素を保持している(吸うが、私は変更することができ自由度ではありません)

だから配列を除いて、このようなものを(に見えるように構成されています8つのノードの行に対して行わ4ノードに1つ - それは、潜在的に数百万行)

[[1,2,3,4,0,0,0,0],   #<- 4 Node quad data packed with zeros 
[3,4,5,6,0,0,0,0],    
[7,8,9,10,11,12,13,14],  #<- 8 node quad in the same table as 4 node quad 
[15,16,17,18,19,20,21,22]] 
Iは、2つの別々のアレイ内にこの情報を分離する必要

を有すること。 4ノード列と1つの8つのノードの行を識別する1 -

[[1,2,3,4],   
[3,4,5,6]] 

[[7,8,9,10,11,12,13,14], 
[15,16,17,18,19,20,21,22]] 

今私は、各行に5値の値をチェックし、2つの索引アレイを作成、2次元アレイを反復です。

for element in elements: 
    if element[5] == 0: 
     tet4indices.append(index) 
    else:   
     tet10indices.append(index) 
    index+=1 

それから私は、2つの配列

tet4s=elements[tet4indices, 0:5] 
tet10s=elements[tet10indices,0:10] 

上記の作品を取得するためにスライスインデックス配列を使用しますが、ちょっと醜いようです。

誰もがよりよい解決策を持っている場合、私はそれを聞いて感謝されると思います.....事前に

おかげで、それが行を見つけるのは簡単だアレイでは

ダグ

+0

にされる別々のグループに4&8エレメント列又は混合? – hpaulj

+0

4行と8行の要素の行を混ぜることができます – max375

+0

@ max375あなたのケースを扱う一般的な答えを追加しました。 – kmario23

答えて

1

ここで、5番目の要素が0、または0でない:

In [75]: arr = np.array(alist) 
In [76]: arr 
Out[76]: 
array([[ 1, 2, 3, 4, 0, 0, 0, 0], 
     [ 3, 4, 5, 6, 0, 0, 0, 0], 
     [ 7, 8, 9, 10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19, 20, 21, 22]]) 
In [77]: arr[:,5] 
Out[77]: array([ 0, 0, 12, 20]) 
In [78]: eights = np.where(arr[:,5])[0] 
In [79]: eights 
Out[79]: array([2, 3], dtype=int32) 
In [80]: arr[eights,:] 
Out[80]: 
array([[ 7, 8, 9, 10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19, 20, 21, 22]]) 
In [81]: fours = np.where(arr[:,5]==0)[0] 
In [82]: arr[fours,:] 
Out[82]: 
array([[1, 2, 3, 4, 0, 0, 0, 0], 
     [3, 4, 5, 6, 0, 0, 0, 0]]) 

またはブールマスクを

In [83]: mask = arr[:,5]>0 
In [84]: arr[mask,:] 
Out[84]: 
array([[ 7, 8, 9, 10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19, 20, 21, 22]]) 
In [85]: arr[~mask,:] 
Out[85]: 
array([[1, 2, 3, 4, 0, 0, 0, 0], 
     [3, 4, 5, 6, 0, 0, 0, 0]]) 

あなたはこの意味を明確にすることが幸いです0マーカーです。いくつかの有限要素コードはノード番号を複製して番号を減らします。 4ノードシステムの3ノード要素の[1,2,3,3]。しかし、これらのケースでは、2つのノードを1つにマージしても、残りの数学はうまく動作します。

+0

これらのソリューションのためにhpauljに感謝します。彼らはどちらも同じスピードを持つように見え、この機能で費やされた時間を6.5秒から1秒に減らし、配列6,500,000のtet10要素を削減しました! – max375

0

これが私の作品:

a=np.split(your_numpy_array,[4],1) 
tet4s=np.vstack([a[0][i,:] for i in range(len(a[0])) if np.sum(a[1][i,:])==0]) 
tet10s=np.vstack([np.hstack((a[0][i,:],a[1][i,:])) for i in range(len(a[0])) if np.sum(a[1][i,:])>0]) 
0

このコードは、あなたのユースケースを処理するのに十分な汎用的です。つまり、行が混在していても両方の場合の例を以下に示します。

行が順序である例:

In [41]: arr 
Out[41]: 
array([[ 1, 2, 3, 4, 0, 0, 0, 0], 
     [ 3, 4, 5, 6, 0, 0, 0, 0], 
     [ 7, 8, 9, 10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19, 20, 21, 22]]) 

# extract first half 
In [85]: zero_rows = arr[~np.all(arr, axis=1), :] 

In [86]: zero_rows 
Out[86]: 
array([[1, 2, 3, 4, 0, 0, 0, 0], 
     [3, 4, 5, 6, 0, 0, 0, 0]]) 

# to trim the trailing zeros in all the rows 
In [84]: np.apply_along_axis(np.trim_zeros, 1, zero_rows) 
Out[84]: 
array([[1, 2, 3, 4], 
     [3, 4, 5, 6]]) 



# to extract second half 
In [42]: mask_nzero = np.all(arr, axis=1) 

In [43]: arr[mask_nzero, :] 
Out[43]: 
array([[ 7, 8, 9, 10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19, 20, 21, 22]]) 

行が混合アップされている例:

In [98]: mixed 
Out[98]: 
array([[ 3, 4, 5, 6, 0, 0, 0, 0], 
     [ 7, 8, 9, 10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19, 20, 21, 22], 
     [ 1, 2, 3, 4, 0, 0, 0, 0]]) 

In [99]: zero_rows = mixed[~np.all(mixed, axis=1), :] 

In [100]: zero_rows 
Out[100]: 
array([[3, 4, 5, 6, 0, 0, 0, 0], 
     [1, 2, 3, 4, 0, 0, 0, 0]]) 

In [101]: np.apply_along_axis(np.trim_zeros, 1, zero_rows) 
Out[101]: 
array([[3, 4, 5, 6], 
     [1, 2, 3, 4]]) 

In [102]: mask_nzero = np.all(mixed, axis=1) 

In [103]: mixed[mask_nzero, :] 
Out[103]: 
array([[ 7, 8, 9, 10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19, 20, 21, 22]])