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