簡體   English   中英

Python / numpy數組分區

[英]Python/numpy array partitioning

我正在使用Python 3.6和numpy。

從hdf5文件中,我讀取了一個二維數組表的一列。

數組的每一行都包含一個有限元節點的ID。

該表的結構使其在同一張表中同時包含了低階和高階元素(這很糟糕,但不是我可以更改的自由度)

因此,數組看起來像這樣(除了它可能有數百萬行)

[[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]]

我需要將此信息分成兩個單獨的數組-一個用於4個節點,一個用於8個節點行。

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

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

現在,我正在遍歷2D數組,檢查每行中第5個值的值,並創建兩個索引數組-一個標識4個節點行,一個標識8個節點行。

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

然后我使用索引數組切片來獲取兩個數組

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

上面的作品,但似乎有點丑陋。

如果有人有更好的解決方案,我將不勝感激。

提前致謝,

道格

在數組中,很容易找到第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個,其余的數學工作也很好。

這對我有用:

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])

此代碼足夠通用,可以處理您的用例。 即,即使您的行混合在一起。 兩種情況的示例如下。

行按順序排列的示例:

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]])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM