简体   繁体   中英

Fast and Clean way to find to find Numpy arrays index

I'll try to be clear. The problem is:

I have two arrays, ELEM and LAMI.

The ELEM array contains information of a Finite Element model, it is of type:

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

so typical data for ELEM is:

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

Now, LAMI contains data for a lamination sequences that can be used for the elements of ELEM. LAMI is of type:

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

So, for example

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

As it can be seen, ELEM['sets'][1] is the name of the material of the element, the material properties of the element are stores in LAMI['cons'].

And the question is: Whichs is the best way to find the array of material properties for an element? I've tried the following:

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

But I'm sure there must be a better way to do that. Thanks!

In this case, a dictionary would probably be preferred:

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

Converting the array to a dictionary would simplify the access a bit

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

Another approach would be to define a Material class, so each material is an object. The ELEM array could then have an object field with these pointers.

Do you ever use LAMI['cons'] as a whole array? If not the structured array format might not be all that useful.


A version using a Material object:

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

producing:

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

But to get a list of the cons of all elements I'd have to use a comprehension:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM