快速而干净的方式来查找Numpy数组索引

时间:2014-08-07 18:26:51

标签: python arrays numpy

我会尽力清楚。问题是:

我有两个阵列,ELEM和LAMI。

ELEM数组包含有限元模型的信息,它的类型为:

ndtype= [('conn','i4',3),('sets','a12',2)] 

ELEM的典型数据是:

array([ ([47, 49, 36], ['web', 'gelcoat']),
([48, 30, 43], ['surf', 'balsa']),...])

现在,LAMI包含可用于ELEM元素的层压序列的数据。 LAMI的类型为:

ndtype = [('name', 'a12', 1), ('type', 'a12', 1), ('cons', 'float64', 6)]

所以,例如

In[1]:LAMI
Out[1]:array([ ('udfrp', 'TRISOTROPIC', [37.0, 90.0, 4.0, 4.0, 0.28, 1860.0]),
           ('dbfrp', 'TRISOTROPIC', [10.0, 10.0, 8.0, 8.0, 0.3, 1830.0]),
           ('gelcoat', 'ISOTROPIC', [10.0, 0.3, 1830.0, 0.0, 0.0, 0.0]),
           ('nexus', 'ISOTROPIC', [1.0, 0.3, 1664.0, 0.0, 0.0, 0.0]),
       ('balsa', 'TRISOTROPIC', [10.0, 10.0, 2.0, 2.0, 0.3, 128.0])], 
      dtype=[('name', 'S12'), ('type', 'S12'), ('cons', '<f8', (6,))])

可以看出,ELEM ['sets'] [1]是元素材质的名称,元素的材质属性存储在LAMI ['cons']中。

问题是:哪个是找到元素的材质属性数组的最佳方法?我尝试了以下内容:

index = np.where(LAMI['name'][0] == ELEM['sets'][element,1])]
prop_array = LAMI['cons'][index]

但我相信必须有更好的方法来做到这一点。谢谢!

2 个答案:

答案 0 :(得分:1)

在这种情况下,可能首选dictionary

In [4]: LAMId = {x['name']: LAMI[['type','cons']][i] for i, x in enumerate(LAMI)}

In [5]: LAMId['udfrp']
Out[5]: ('TRISOTROPIC', [37.0, 90.0, 4.0, 4.0, 0.28, 1860.0])

In [6]: LAMId['udfrp']['cons']
Out[6]: 
array([  3.70000000e+01,   9.00000000e+01,   4.00000000e+00,
         4.00000000e+00,   2.80000000e-01,   1.86000000e+03])

答案 1 :(得分:1)

将数组转换为字典会简化访问次数

In [163]: Ldict={}
In [166]: for r in LAMI:
   .....:     Ldict[r['name']]={'type':r['type'],'cons':r['cons']}

In [176]: name=ELEM['sets'][0,1]

In [177]: LAMI[np.where(LAMI['name']==name)]['cons']
Out[177]: 
array([[  1.00000000e+01,   3.00000000e-01,   1.83000000e+03,
          0.00000000e+00,   0.00000000e+00,   0.00000000e+00]])

In [178]: Ldict[name]['cons']
Out[178]: 
array([  1.00000000e+01,   3.00000000e-01,   1.83000000e+03,
         0.00000000e+00,   0.00000000e+00,   0.00000000e+00])

另一种方法是定义Material类,因此每个material都是一个对象。然后,ELEM数组可以包含带有这些指针的object字段。

您是否曾使用LAMI['cons']作为整个数组?如果不是,结构化数组格式可能不是那么有用。


使用Material对象的版本:

class Material(object):
    def __init__(self, name, _type, cons):
        self.name = name
        self.type = _type
        self.cons = cons.tolist() # more compact display
    def __repr__(self):
        return str((self.name, self.type, self.cons))
Ldict = {}
for r in LAMI:
    Ldict[r['name']] = Material(r['name'], r['type'], r['cons'])

dset = np.dtype([('where','a12'),('material','O')])
dtElem = np.dtype([('conn', '<i4', (3,)), ('sets', dset)])
# nested dtypes
# [('conn', '<i4', (3,)), ('sets', [('where', 'S12'), ('material', 'O')])]

ELEM = np.array([ ([47, 49, 36], ('web', Ldict['gelcoat'])),
                  ([48, 30, 43], ('surf', Ldict['balsa']))],
               dtype=dtElem)

print 'ELEM array'
print ELEM
print 'material properties of one element'
print ELEM[0]['sets']['material'].cons
print 'materials of all elements'
print ELEM['sets']['material']
制造

ELEM array
[ ([47, 49, 36], ('web', ('gelcoat', 'ISOTROPIC', [10.0, 0.3, 1830.0, 0.0, 0.0, 0.0])))
 ([48, 30, 43], ('surf', ('balsa', 'TRISOTROPIC', [10.0, 10.0, 2.0, 2.0, 0.3, 128.0])))]

material properties of one element
[10.0, 0.3, 1830.0, 0.0, 0.0, 0.0]

materials of all elements
[('gelcoat', 'ISOTROPIC', [10.0, 0.3, 1830.0, 0.0, 0.0, 0.0])
 ('balsa', 'TRISOTROPIC', [10.0, 10.0, 2.0, 2.0, 0.3, 128.0])]

但要获得所有元素cons的列表,我必须使用理解:

print [m.cons for m in ELEM['sets']['material']]