Python - 用第二个数组的2个值替换数组的数据

时间:2015-11-14 20:23:37

标签: python arrays numpy

我有两个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]):

2 个答案:

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

使用广播将en进行比较 - 这会产生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.]])