找到给定shell的相应实体

时间:2017-07-05 08:25:47

标签: python python-2.5

我正在研究的问题是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];

1 个答案:

答案 0 :(得分:0)

  

问题:是否可以轻松地将复杂度从O(mn)降低到更快的速度?

  

注意:您的Python版本已过时,无法使用您的注释。

  1. 使用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
    
  2. 使用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]
    
  3. 替代
    使用numpy.isin代替numpy.in1d
    无法尝试,因为它是版本1.13.0中的新功能。

    我可以想象pandas可以解决这个问题。

  4. 使用Python测试:3.4.2 - numpy:1.12.1