I have a dictionary defined as follows:
>>> mydict = {0:obj0,5:obj1,4:obj3,7:obj4}
The dictionary has integer as keys.
I am trying to convert this dict to a numpy array.
so that:
>>> nparray[[4,0]] = [obj3,obj0]
>>> nparray[[7,4]] = [obj4,obj3]
I am aware of numpy structured arrays but unfortunately it seems like integer indexes must correspond to the position in the array as opposed to the key. Is there a way to change this behavior.
I was considering a way to "trick" the numpy array. For example instead of reading [4,0] it reads the rows corresponding to those keys.
My end goal is to have some sort of custom class that inherits from np.ndarray, if there isn't another alternative.
UPDATE
A bit more background, I originally solved this problem by using the class below, which stores the objects:
class MyArray (dict):
def __init__ (self,*args):
dict.__init__(self,*args)
def __getitem__ (self, key):
if not hasattr (key, '__iter__'):
return dict.__getitem__ (self,key)
return List([dict.__getitem__ (self,k) for k in key])
Which allows multi-key indexes. The key array can be very huge (1000000+), and so for k in key can take a long time and/or be expensive. I wanted to use numpy arrays to take advantage of it's speed, lower memory etc.. and wouldn't have to use that for loop. Is it still warranted?
Lets make the dictionary; here my obj
are tuples (just for convenience):
In [563]: mydict={0:(0,),5:(1,),4:(3,),7:(4,)}
In [564]: mydict
Out[564]: {0: (0,), 4: (3,), 5: (1,), 7: (4,)}
Initial an array that's big enough and dtype=object:
In [565]: A=np.empty((8,),dtype=object)
In [566]: A
Out[566]: array([None, None, None, None, None, None, None, None], dtype=object)
copy values from mydict
to A
, using the key as the array index:
In [567]: for k in mydict:
.....: A[k]=mydict[k]
.....:
In [568]: A
Out[568]: array([(0,), None, None, None, (3,), (1,), None, (4,)], dtype=object)
In [574]: A[[4,0]]
Out[574]: array([(3,), (0,)], dtype=object)
In [575]: A[[7,4]]
Out[575]: array([(4,), (3,)], dtype=object)
Items defined in the dictionary now appear in the corresponding slots in the array. I won't make any claims about this being useful.
I could mask the nones
.
In [581]: Am=np.ma.masked_array(A)
In [582]: Am.mask=[False,True,True,True,False,False,True,False]
In [583]: Am
Out[583]:
masked_array(data = [(0,) -- -- -- (3,) (1,) -- (4,)],
mask = [False True True True False False True False],
fill_value = ?)
The nones
are still there, just 'hidden'. I don't know if masking does anything useful with object types.
From comments it sounds like the main thing you want is the ability to select multiple items from a dictionary, something akin to the array A[[0,3,5]]
indexing.
It might be easier to subclass dict
than to expand or subclass np.ndarray
.
scipy.sparse
has a sparse matrix format which is a subclass of dict. It's __getitem__
may give ideas on how to extend your own dict. I'll try to come up with a simpler version.
In mean time, one way to fetch a group of keys is with an expression like:
In [646]: {k:mydict[k] for k in mydict if k in {0,4}}
Out[646]: {0: (0,), 4: (3,)}
or simpler
In [647]: {k:mydict[k] for k in [0,4]}
Out[647]: {0: (0,), 4: (3,)}
but more robust:
In [649]: {k:mydict.get(k,None) for k in [0,4,5,10]}
Out[649]: {0: (0,), 4: (3,), 5: (1,), 10: None}
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.