Python 快速而干净的查找Numpy数组索引的方法

Python 快速而干净的查找Numpy数组索引的方法,python,arrays,numpy,Python,Arrays,Numpy,我会尽量澄清的。问题是: 我有两个数组,ELEM和LAMI ELEM阵列包含有限元模型的信息,其类型为: ndtype= [('conn','i4',3),('sets','a12',2)] ndtype = [('name', 'a12', 1), ('type', 'a12', 1), ('cons', 'float64', 6)] 因此,ELEM的典型数据为: array([ ([47, 49, 36], ['web', 'gelcoat']), ([48, 30, 43], ['s

我会尽量澄清的。问题是:

我有两个数组,ELEM和LAMI

ELEM阵列包含有限元模型的信息,其类型为:

ndtype= [('conn','i4',3),('sets','a12',2)] 
ndtype = [('name', 'a12', 1), ('type', 'a12', 1), ('cons', 'float64', 6)]
因此,ELEM的典型数据为:

array([ ([47, 49, 36], ['web', 'gelcoat']),
([48, 30, 43], ['surf', 'balsa']),...])
现在,LAMI包含可用于ELEM元素的层压序列的数据。LAMI属于以下类型:

ndtype= [('conn','i4',3),('sets','a12',2)] 
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,))])
但我相信一定有更好的办法。谢谢

在这种情况下,a可能是首选:

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

将数组转换为字典将稍微简化访问

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']
作为一个整体使用过?如果不是的话,结构化数组格式可能就没那么有用了


使用材质对象的版本:

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']
但要获得所有元素的
缺点列表,我必须使用理解:

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

如果有效,为什么要更改?因为语法非常不清楚,而且很难阅读。@Martin我在ELEM表中看不到任何名为
set
的列。你能发布完整的数据或更多的细节吗?@Dalek,实际上有一个列叫做set,ndtype=[('conn','i4',3),('sets','a12',2)]谢谢你的回复。实际上,我没有将LAMI数组用作数组,而只是用作数据容器。如果我在ELEM['set']中存储一个对象,可能会有额外的成本吗?这个
dtype
应该同样好:
dtype([(‘conn’,‘我画了一个材质对象的变体,并且在
ELEM
中有一个字段指出了这一点。对于某些任务,类封装很好,对于其他任务,数组和表更好。非常好的hpaulj!这对我帮助很大,这是我将遵循的方法,我认为这种方法没有额外的成本,因为尽管有对于许多元素,ELEM数组只存储指向material对象的指针。由于模型中的材质很少,实例化和对象从数组中过度读取属性的额外成本可以忽略不计。再次感谢!感谢香蕉!这是我将要做的一部分,其余部分遵循hpaulj推荐和存储元素中包含指向材质属性对象指针的列中的材质属性。