Package: dacc
daccA declarative approach to data access object constructionThe idea is to be able to specify a DAG (Directed Acyclic Graph) of data
dependencies, and only have to retrieve or compute datas as they are needed.This is an older solution, that will soon be replaced with a more modern approach,
involving properties and cached_properties...ExampleHere is a full, and real, example of usage.Here we tap into some website visitor data (in mongoDB) that has IP addresses for every visit,
and use those to get approximate geo-coordinates for the visit.fromut.util.data_flowimportDataFlowfrompymongoimportMongoClientimportpygeoipfrompandasimportDataFramefromcollectionsimportCountertraj_names={'ip':'IP','date':'date'}event_names={'audience_volume':'audience_volume','broadcast_population_range':'broadcast_population_range','broadcast_hard_radius':'broadcast_hard_radius'}ip_geo_data_filepath='~/Data/geo/geoip/GeoLiteCity.dat'# GeoIP.dat?traj_mongo_db='fuak'traj_mongo_collection='visits'gi=pygeoip.GeoIP(ip_geo_data_filepath)defget_location_info(ip):geo=gi.record_by_addr(ip)return{'lat':geo.get('latitude'),'lon':geo.get('longitude')}ip_2_latlon=get_location_infotraj_data=MongoClient()[traj_mongo_db][traj_mongo_collection]classTrajFeatBuilder(DataFlow):def__init__(self,ip_geo_data_filepath=ip_geo_data_filepath,**kwargs):params=dict()params['data_dependencies']={'ip_list':['visitor_id'],'ip_counts':['ip_list'],'latlon_counts':['ip_counts']}params['data_makers']={k:params[k]forkinparams['data_dependencies'].keys()ifkinparams.keys()}kwargs=dict(kwargs,**params)super(TrajFeatBuilder,self).__init__(**kwargs)self.ip_2_latlon=get_location_infoself.traj_data=MongoClient()[traj_mongo_db][traj_mongo_collection]defget_features(self,**kwargs):visitor_id=kwargs.get('visitor_id',None)ifvisitor_id:ip_counts=self._ip_list_to_ip_counts(ip_list=self._visitor_id_to_ip_list(visitor_id=visitor_id))# ip_counts = self._visitor_id_to_ip_list(visitor_id=visitor_id)# ip_counts = Counter([x['ip'] for x in self.traj_data.find({'visitor_id': visitor_id},#                                                           fields={'_id': False, 'ip': True})])iflen(ip_counts)==0:returnNoneelse:location_counts=DataFrame(map(self.ip_2_latlon,ip_counts.keys()))location_counts['count']=ip_counts.values()return{'visitor_id':visitor_id,'location_counts':self._ip_counts_to_latlon_counts(ip_counts)}else:raiseValueError('Unknown traj format (should be a visitor_id)')defip_list(self,visitor_id,**kwargs):return[x['ip']forxinself.traj_data.find({'visitor_id':visitor_id},fields={'_id':False,'ip':True})]defip_counts(self,ip_list,**kwargs):returnCounter(ip_list)deflatlon_counts(self,ip_counts,**kwargs):latlon_counts=DataFrame(map(self.ip_2_latlon,ip_counts.keys()))latlon_counts['count']=ip_counts.values()returnlatlon_countsMake the object:dflow=TrajFeatBuilder(verbose_level=10)Get anip_listfor a given visitordflow.get_data('ip_list',visitor_id='201411301840218052872011')['86.73.225.225',
 '86.73.225.225',
 '84.103.117.129',
 '84.103.117.129',
 '84.103.117.129',
 '84.103.117.129',
 '84.103.117.129',
 '84.103.117.129',
 '84.103.117.129',
 '84.103.117.129',
 '84.103.117.129',
 '84.103.117.129',
 '84.103.117.129',
 '84.103.117.129',
 '86.73.225.248',
 '86.73.225.225',
 '86.73.225.225',
 '86.73.225.225',
 '86.73.225.225',
 '86.73.225.225',
 '86.73.225.225',
 '86.73.225.225']Get a count of the locations coordinates where visitor was present.dflow.get_data('latlon_counts',visitor_id='201411301840218052872011')latloncount048.92582.44531148.91022.553212248.92582.44539