Python/numpy数组分区 [英] Python/numpy array partitioning
问题描述
我正在使用Python 3.6和numpy.
I'm using Python 3.6 and numpy.
我从hdf5文件中读取了一个表的一列,该表是2D数组.
From an hdf5 file I read a column of a table that is a 2D array.
数组的每一行都包含一个有限元节点的ID.
Each row of the array holds the ID's of the nodes of a finite element.
表的结构使得它在同一张表中同时包含了低阶和高阶元素(这很糟糕,但不是我可以更改的自由度)
The table is structured such that it holds both lower and higher order elements in the same table (which sucks, but is not a degree of freedom I can change)
所以数组看起来像这样(除了它可能有数百万行)
So the array looks something like this (except that it has potentially millions of rows)
[[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个节点行.
I need to separate this info into two separate arrays - one for the 4 node an done for 8 node rows.
[[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个节点行.
Right now I'm iterating over the 2D array, checking the value of the 5th value in each row and creating two index arrays - one identifying the 4 node rows and one the 8 node rows.
for element in elements:
if element[5] == 0:
tet4indices.append(index)
else:
tet10indices.append(index)
index+=1
然后我使用索引数组切片来获取两个数组
Then I use index array slicing to get the two arrays
tet4s=elements[tet4indices, 0:5]
tet10s=elements[tet10indices,0:10]
以上方法有效,但看起来有点难看.
The above works, but seems kinda ugly.
如果有人有更好的解决方案,我将不胜感激.....
If anyone has a better solution, I'd be grateful to hear about it.....
预先感谢
道格
推荐答案
在数组中,很容易找到第5个元素为0或不为0的行:
In an array it's easy to find rows where the 5th element is 0, or not 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
标记.一些有限元代码重复节点编号以减少数量,例如[1,2,3,3]适用于4节点系统中的3节点元素.但是在那种情况下,即使将2个节点合并为1个,其余的数学工作也很好.
You are lucky, in a sense, to have this clear 0
marker. Some finite element code duplicates node numbers to reduce the number, e.g. [1,2,3,3] for a 3 node element in a 4 node system. But in those cases the rest of the math works fine, even when you merge 2 nodes into one.
这篇关于Python/numpy数组分区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!