Source code for cellcomplex.utils.array_dict

import numpy as np
from scipy import ndimage as nd

[docs]def isiterable(obj): try: iter(obj) return True except: return False
[docs]class array_dict: def __init__(self, values= np.array([]), keys = None): if isinstance(values,array_dict): from copy import deepcopy self._values = deepcopy(values._values) self._keys = deepcopy(values._keys) self._index = deepcopy(values._index) elif isinstance(values,dict): self._values = np.array(list(values.values())) self._keys = np.array(list(values.keys())) #self._index = np.array(nd.sum(np.arange(len(values)),self._keys,index=np.arange(max(self._keys)+1)),int) self._index = np.zeros(self._keys.max()+1,int) self._index[self._keys] = np.arange(len(self._keys)) elif isinstance(values,list) and isinstance(values[0],tuple): self._values = np.array(values)[:,1] self._keys = np.array(np.array(values)[:,0],int) #self._index = np.array(nd.sum(np.arange(len(values)),self._keys,index=np.arange(max(self._keys)+1)),int) self._index = np.zeros(self._keys.max()+1,int) self._index[self._keys] = np.arange(len(self._keys)) else: self._values = np.array(list(values)) if not keys is None: assert len(keys) == len(values) self._keys = np.array(list(keys)) #self._index = np.array(nd.sum(np.arange(len(values)),self._keys,index=np.arange(max(self._keys)+1)),int) self._index = np.zeros(self._keys.max()+1,int) self._index[self._keys] = np.arange(len(self._keys)) else: if len(values)>0: self._keys = np.arange(len(values)) self._index = np.arange(len(values)) else: self._keys = np.array([],int) self._index = np.array([],int) def __getitem__(self,key): if self._index[key] > 0: return self._values[self._index[key]] elif key in self._keys: return self._values[0] else: raise KeyError(str(key)) def __setitem__(self,key, value): import numpy as np if key in self._keys: self._values[self._index[key]] = value else: newindex = len(self._values) self._keys = np.append(self._keys,np.array([key]),axis=0) if key<len(self._index): self._index[key] = newindex else: new_index = np.zeros(key+1,int) new_index[0:len(self._index)] = self._index new_index[key] = newindex self._index = new_index if len(self) == 0: self._values = np.array([value]) else: self._values = np.append(self._values,np.array([value]),axis=0) def __delitem__(self, key): index = self._index[key] self._values = np.delete(self._values,index,axis=0) self._index[self._keys[index:]] -= 1 self._keys = np.delete(self._keys,index,axis=0) self._index[key] = 0 def __len__(self): return len(self._values) def __str__(self): self.dict_string = "{" for i,k in enumerate(self._keys): self.dict_string = self.dict_string+str(k)+": "+str(self._values[self._index[k]]) if i < self._values.size-1 : self.dict_string = self.dict_string+", " self.dict_string = self.dict_string+"}\n" return self.dict_string def __repr__(self): self.dict_string = "{" if len(self)<10: for i,k in enumerate(self._keys): self.dict_string = self.dict_string+str(k)+": "+str(self._values[i]) if i < self._values.size-1 : self.dict_string = self.dict_string+", " else: for i in range(3): self.dict_string = self.dict_string+str(self._keys[i])+": "+str(self._values[i])+"," self.dict_string = self.dict_string+"..." for i in range(3): self.dict_string = self.dict_string+","+str(self._keys[len(self)-3+i])+": "+str(self._values[len(self)-3+i]) self.dict_string = self.dict_string+"}\n" return self.dict_string
[docs] def to_dict(self): return dict([(tuple(k),self._values[i]) if isiterable(k) else (k,self._values[i]) for i,k in enumerate(self._keys)])
[docs] def values(self,keys=None): if keys is None: return self._values[self._index[self._keys]] else: if not isinstance(keys,np.ndarray): keys = np.array(keys) if keys.dtype == np.dtype('O'): return np.array([self.values(k) for k in keys]) else: return self._values[self._index[keys]]
[docs] def keys(self) : return self._keys
[docs] def items(self): return [(k,self._values[i]) for i,k in enumerate(self._keys)]
[docs] def update(self,values,keys=None,ignore_missing_keys=True,erase_missing_keys=True): if keys is None or (len(keys) == len(self._keys) and (keys==self.keys()).all()): assert len(self) == len(values) self._values = values else: assert len(keys) == len(values) keys_to_assign = np.intersect1d(keys,self._keys) if len(keys_to_assign)!=len(keys): key_range = np.array(nd.sum(np.arange(keys.size),keys,index=keys_to_assign),int) self._values[self._index[keys_to_assign]] = values[key_range] if ignore_missing_keys: print("Warning : some keys were missing from dictionary! (values ignored)") else: print("Warning : missing keys were added to the dictionary!") missed_keys = np.array(tuple(set(keys).difference(set(self._keys)))) newindex = np.arange(len(self._values),len(self._values)+len(missed_keys)) self._keys = np.append(self._keys,missed_keys,axis=0) if missed_keys.max()<len(self._index): self._index[missed_keys] = newindex else: new_index = np.zeros(missed_keys.max()+1,int) new_index[0:len(self._index)] = self._index new_index[missed_keys] = newindex self._index = new_index key_range = np.array(nd.sum(np.arange(keys.size),keys,index=missed_keys),int) if len(self) == 0: self._values = np.array(values[key_range]) else: self._values = np.append(self._values,values[key_range],axis=0) else: if len(keys_to_assign)!=len(self._keys) or (keys!=self.keys()).any(): if erase_missing_keys: print("Warning : missing keys were erased from the dictionary!") self._values = values self._keys = np.array(keys) self._index = np.zeros(self._keys.max()+1,int) self._index[self._keys] = np.arange(len(self._keys)) else: self._values[self._index[keys]] = values else: self._values[self._index[keys]] = values
[docs] def delete(self,keys_to_delete): keys_to_delete = np.intersect1d(keys_to_delete,self._keys) if len(keys_to_delete)>0: indices_to_delete = self._index[keys_to_delete] self._values = np.delete(self._values,indices_to_delete,0) self._keys = np.delete(self._keys,indices_to_delete,0) self._index[keys_to_delete] = 0 self._index[self._keys] = np.arange(len(self._keys))
[docs] def has_key(self, key): return key in self._keys
# def values(self): # return self.to_dict().values() # def keys(self): # return self.to_dict().keys() # def items(self): # return self.to_dict().items()
[docs] def keys_where(self,criterion): if isinstance(criterion,str): return self._keys[np.where(eval('self._values'+criterion))] elif isinstance(criterion,tuple) & isinstance(criterion[0],str): expression = '(self._values'+criterion[0]+')' for c in criterion[1:]: expression += '& (self._values'+c+')' return self._keys()[np.where(eval(expression))] else: assert len(criterion) == len(self._keys) return self._keys[np.where(criterion)]