我有两个numpy数组" Elements"和"节点"。我的目标是聚集 这些数组的一些数据。 我需要重新塑造" Elements"两个坐标的两个最后一列的数据包含在"节点"阵列。 这两个阵列非常庞大,我必须自动化它。
一个例子:
import numpy as np
Elements = np.array([[1.,11.,14.],[2.,12.,13.]])
nodes = np.array([[11.,0.,0.],[12.,1.,1.],[13.,2.,2.],[14.,3.,3.]])
results = np.array([[1., 0., 0., 3., 3.],
[2., 1., 1., 2., 2.]])
我认为"如果"和#34; for循环"有可能这样做,但我不知道如何追加结果......
test=[]
for i in range(Elements.shape[0]):
if (Elements[:,:1] == nodes[i,0]):
答案 0 :(得分:2)
您可以考虑在循环之前创建结果数组,而不是将结果附加到某个数组或列表。
这是我使用fop循环和np.where的问题的解决方案。
import numpy as np
# I used numpy 1.10.1 here
Elements = np.array([[1.,11.,14.],[2.,12.,13.]])
nodes = np.array([[11.,0.,0.],[12.,1.,1.],[13.,2.,2.],[14.,3.,3.]])
# Create an array with enough rows and five columns
res = np.zeros((np.shape(Elements)[0],5))
for i in range(np.shape(Elements)[0]):
res[i,0] = Elements[i,0] # The first column stays the same
# Find the Value of the 2nd column of Elements in the first column of nodes.
nodesindex = np.where(nodes[:,0]==Elements[i,1])
# Replace second and third row of the results with the ventries from nodes.
res[i,1:3]=nodes[nodesindex,1:3]
#Do the same for the 3rd column of Elements
nodesindex = np.where(nodes[:,0]==Elements[i,2])
res[i,3:5]=nodes[nodesindex,1:3]
print(res)
作为输出
[[ 1. 0. 0. 3. 3.]
[ 2. 1. 1. 2. 2.]]
可能存在纯粹的numpy解决方案(没有for-loop)。那可能比这快得多。
答案 1 :(得分:1)
这是一个不使用循环的版本:
输入:
In [115]: Elements = np.array([[1.,11.,14.],[2.,12.,13.]])
In [116]: nodes = np.array([[11.,0.,0.],[12.,1.,1.],[13.,2.,2.],[14.,3.,3.]])
来自Elements
的ID作为向量;将其设为int
以便于比较:
In [117]: e = Elements[:,1:].ravel().astype(int)
In [118]: e
Out[118]: array([11, 14, 12, 13])
来自nodes
的类似ID:
In [119]: n=nodes[:,0].astype(int)
In [120]: n
Out[120]: array([11, 12, 13, 14])
使用广播将e
与n
进行比较 - 这会产生4x4的True / False数组。使用where
查找其坐标:
In [121]: I, J = np.where(e==n[:,None])
In [122]: I
Out[122]: array([0, 1, 2, 3], dtype=int32)
In [123]: J
Out[123]: array([0, 2, 3, 1], dtype=int32)
In [124]: e[J]
Out[124]: array([11, 12, 13, 14])
In [125]: n[I]
Out[125]: array([11, 12, 13, 14])
神奇地说,我们现在可以将节点ID与元素ID进行匹配。如果此操作不明确,请打印一些中间数组。
制作results
数组,每个e
元素一行,并复制相应的nodes
值。
In [131]: results = np.zeros((e.shape[0],2),nodes.dtype)
In [132]: results[J] = nodes[I,1:]
In [133]: results
Out[133]:
array([[ 0., 0.],
[ 3., 3.],
[ 1., 1.],
[ 2., 2.]])
使用元素的初始列加入results
:
In [134]: np.concatenate((Elements[:,[0]],results.reshape(2,4)),axis=1)
Out[134]:
array([[ 1., 0., 0., 3., 3.],
[ 2., 1., 1., 2., 2.]])
where
执行基本匹配。休息的大部分只是重塑和类型转换,以处理我们需要填充的'槽'是3列Elements数组的2列。
出于好奇,我想出了如何使用Elements ids而不是散乱:
In [149]: e2 = Elements[:,1:].astype(int)
In [150]: I,J,K = np.where(e2==n[:,None,None])
In [151]: results2 = np.zeros((e2.shape[0],e2.shape[1],2),nodes.dtype)
In [152]: results2[J,K] = nodes[I,1:]
In [153]: results2.reshape(2,4) # still requires a reshape
Out[153]:
array([[ 0., 0., 3., 3.],
[ 1., 1., 2., 2.]])