我正在研究的问题是CAE / FEM相关,可归纳如下:
我正在读取包含节点的文件(3D中的点,由节点编号和X / Y / Z坐标定义),三角形外壳元素(由元素编号和3个节点定义)和四面体实体元素(由元素编号和4个节点定义)。数据存储在3个字典中:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
<div class="div">Div one</div>
<div class="div">Div Two</div>
<div class="div">Div Three</div>
<div class="div">Div Four</div>
</div>
<div class="mainLength">
</div>
每个shell都有一个具有相同节点的相应实体:
nodes = {'Node_ID' : [X, Y, Z]};
shells = {'Shell_ID': ['Node_ID_1', 'Node_ID_2', 'Node_ID_3']};
solids = {'Solid_ID': ['Node_ID_1', 'Node_ID_2', 'Node_ID_3', 'Node_ID_4']};
Python需要大约100秒(shell数量约为12,000,实体数量约为40,000,因此if-query必须执行480,000,000次。是否可以将复杂度从O(mn)降低到什么东西更快,省力?
编辑:节点,shell,实体的一些示例:
节点
for shell_k, shell_v in shells.iteritems():
for solid_k, solid_v in solids.iteritems():
if((shell_v[0] in solid_v) and (shell_v[1] in solid_v) and (shell_v[2] in solid_v)):
# This is true for one combination of shell and solid
壳
# In file:
2504888, 190.05780, 101.70673, 320.68655
2504889, 187.96325, 101.82080, 322.86340
2504890, 192.14670, 103.65783, 320.42405
2504891, 188.52980, 105.40890, 320.94880
2504892, 190.05215, 103.77190, 322.60090
# As dict:
nodes[2504888] = [190.05780, 101.70673, 320.68655];
nodes[2504889] = [187.96325, 101.82080, 322.86340];
nodes[2504890] = [192.14670, 103.65783, 320.42405];
nodes[2504891] = [188.52980, 105.40890, 320.94880];
nodes[2504892] = [190.05215, 103.77190, 322.60090];
固体:
# In file:
227, 3866603, 3862785, 3862784
228, 3866603, 3862784, 3866559
229, 3866585, 3866603, 3866559
230, 3866635, 3866603, 3866585
231, 3866208, 3866635, 3866585
# As dict:
shells[227] = [3866603, 3862785, 3862784];
shells[228] = [3866603, 3862784, 3866559];
shells[229] = [3866585, 3866603, 3866559];
shells[230] = [3866635, 3866603, 3866585];
shells[231] = [3866208, 3866635, 3866585];
shell / solid对的一个例子是:
# In file:
3622889, 4130281, 4130283, 4126885, 4126884
3622890, 4130281, 4126885, 4129084, 4126884
3622891, 4130281, 4129084, 4129080, 4126884
3622892, 4129080, 4129084, 4129083, 4126884
3622895, 4129080, 4129083, 4129079, 4126884
# As dict:
solids[3622889] = [4130281, 4130283, 4126885, 4126884];
solids[3622890] = [4130281, 4126885, 4129084, 4126884];
solids[3622891] = [4130281, 4129084, 4129080, 4126884];
solids[3622892] = [4129080, 4129084, 4129083, 4126884];
solids[3622895] = [4129080, 4129083, 4129079, 4126884];
答案 0 :(得分:0)
问题:是否可以轻松地将复杂度从O(mn)降低到更快的速度?
注意:您的Python版本已过时,无法使用您的注释。
使用if condition
set()
for shell_k in shells:
for solid_k in solids:
if set(shells[shell_k]).issubset(set(solids[solid_k])):
# This is true for one combination of shell and solid
或者,前提条件值为set()
类型以消除类型转换:
for shell_k in shells_set:
for solid_k in solids_set:
if shells_set[shell_k].issubset(solids_set[solid_k]):
# This is true for one combination of shell and solid
使用NumPy的解决方案
NumPy v1.13手册:numpy.in1d
numpy.in1d(ar1, ar2, assume_unique=False, invert=False)[source]
测试1-D阵列的每个元素是否也存在于第二个阵列中。 返回一个与ar1相同长度的布尔数组,即True,其中ar1的元素在ar2中,否则为False。
预处理数据为numpy.ndarray的
shells(4, 3): [[3866448 3867528 3867556]
[3862784 3862785 3866603]
[4126884 4126885 4130283]
[3862784 3866559 3866603]]
solids(4, 4): [[3854247 3866448 3867528 3867556]
[4126884 4126885 4130281 4130283]
[4126884 4126885 4129084 4130281]
[4126883 4126885 4129084 4130282]]
solids_id:[3478898 3478899 3478900 3478901]
import numpy as np
# Get a (4,4) numpy Mask from Shells in Solids
solids_in1d = np.in1d(solids, n_shells).reshape(solids.shape)
# Get Array of y Index of Masked Solides with 3 Nodes
solids_idx = np.where(np.sum(solids_in1d, axis=1) == 3)[0]
# Print Solids - Show ID and only the 3 Solid Nodes
for y in solids_idx:
print('Solids ID:{} Nodes:{}'.format(solids_id[y], solids[y][solids_in1d[y]]))
输出:
Solids ID:3478898 Nodes:[3866448 3867528 3867556] Solids ID:3478899 Nodes:[4126884 4126885 4130283]
替代
使用numpy.isin
代替numpy.in1d
无法尝试,因为它是版本1.13.0中的新功能。
我可以想象pandas
可以解决这个问题。
使用Python测试:3.4.2 - numpy:1.12.1