#!/usr/bin/env python3 # -*- coding: UTF-8 -*- from pycen import update_to_sql, con_sicen,con_gn import geopandas as gpd import os DIR = '/home/colas/Documents/9_PROJETS/4_SICEN/GN_MIGRATION' def form_cdnom(data): dict_cdnom = { 116744:521658, # Flore : Quercus petraea } data.replace({'cd_nom':dict_cdnom},inplace=True) data.replace({'cd_ref':dict_cdnom},inplace=True) def form_complx_grp(data): dict_cdnom = { 9999005:105817, # Leucanthemum vulgare (#groupe) 9999014:119097, # Rubus fruticosus (#groupe) 9999017:717630, # Taraxacum officinale (#groupe) 9999019:126573, # Thymus serpyllum (#groupe) 9999020:129298, # Vicia sativa (#groupe) 9999023:188772, # Acrocephalus palustris / scirpaceus (#complexe) 9999031:441709, # Cairina moschata f. domestica (#forme) 9999033:190350, # Carduelis flammea flammea / cabaret / Carduelis hornemanni (#complexe) 9999037:191029, # Colias alfacariensis / hyale (#complexe) 9999041:4503, # Corvus corone corone / cornix (#complexe) 9999042:186239, # Eptesicus / Nyctalus sp. (#complexe) 9999046:192539, # Felis silvestris / catus (#complexe) 9999050:193993, # Leptidea sinapis / reali (#complexe) 9999054:194481, # Martes martes / foina (#complexe) 9999057:195005, # Myotis myotis / blythii (#complexe) 9999063:444436, # Pelophylax kl. esculentus / lessonae (#complexe) 9999064:4280, # Phylloscopus collybita tristis / "abietinus" (#complexe) 9999066:196980, # Pyrgus malvae / malvoides (#complexe) 9999074:197040, # Rana dalmatina / temporaria (#complexe) 9999075:196296, # Pipistrellus nathusii / kuhlii (#complexe) 9999080:194357, # Lysandra coridon / hispana (#complexe) 9999082:195005, # Myotis daubentonii / Myotis mystacinus (#complexe) 9999083:699094, # Pipistrellus / Miniopterus (#complexe) } lst_cdnom_old = [*dict_cdnom.keys()] if data.cd_nom.isin(lst_cdnom_old).any(): data.loc[data.cd_nom.isin(lst_cdnom_old),'complexe_groupe'] = data[data.cd_nom.isin(lst_cdnom_old)].nom_complet data.replace({'cd_nom':dict_cdnom},inplace=True) sql = 'SELECT cd_nom, nom_complet nom_new FROM taxonomie.taxref where cd_nom in {}'.format(tuple(dict_cdnom.values())) tax = gpd.pd.read_sql(sql, con_gn) data = data.merge(tax,how='left',on='cd_nom') data.loc[data.nom_new.notna(),'nom_latin'] = data[data.nom_new.notna()].nom_new data.drop(columns='nom_new',inplace=True) def correct_taxonomie(data): dict_taxo = { 444440:'Pelophylax kl\. esculentus \(Linnaeus, 1758\)' } for k,v in dict_taxo.items(): is_saisie = data.rmq_observation.str.contains(v,na=False) if not is_saisie.any(): continue data.loc[is_saisie,'nom_latin'] = v data.loc[is_saisie,'cd_nom'] = k data.loc[is_saisie,'cd_ref'] = k def form_precision(data): dict_pre = { 'GPS':0, '0 à 10m':10, '10 à 100m':100, '100 à 500m':500, 'lieu-dit':750, 'commune':None, } is_com = data.precision =='commune' rmq_null = data.rmq_localisation.isnull() data.loc[is_com&rmq_null,'rmq_localisation'] = 'Localisation : commune' data.loc[is_com&~rmq_null,'rmq_localisation'] = 'Localisation : commune ;'+data[is_com].rmq_localisation data.replace({'precision':dict_pre},inplace=True) data.precision = data.precision.astype('Int64') def form_effectif(data): eff_notna = data.effectif.notna() efmin_notna = data.effectif_min.notna() efmax_isna = data.effectif_max.isna() data.loc[(~eff_notna)&efmin_notna,'effectif'] = data[(~eff_notna)&efmin_notna].effectif_min data.loc[(~eff_notna)&(~efmax_isna),'effectif'] = data[(~eff_notna)&(~efmax_isna)].effectif_max # data.loc[efmax_isna,'effectif_max'] = data[efmax_isna].effectif data.effectif = data.effectif.astype('Int64') data.effectif_max = data.effectif_max.astype('Int64') t1 = data.effectif_min < data.effectif data.loc[t1,'effectif_max'] = data[t1].effectif data.loc[t1,'effectif'] = data[t1].effectif_min # Est trop incertain... Les effectifs récupérés sont < aux effectifs déclarés # ==> Incompréhansion, Ne sera pas utilisé def recup_faune_eff(data): # Récupération des effectifs standardisés du champ rmq_observation ismixte = data.rmq_observation.str.contains('\\d.00 Mâle\(s\) et \\d.00 Femelle\(s\)',na=False) ismal = data.rmq_observation.str.contains('\\d.00 Mâle\(s\) et \? Femelle\(s\)',na=False) isfem = data.rmq_observation.str.contains('\? Mâle\(s\) et \\d.00 Femelle\(s\)',na=False) data.loc[ismixte,'extract_eff'] = (data[ismixte].rmq_observation .str.extract('(\d+).00 Mâle\(s\) et (\d+).00 Femelle\(s\)').astype(int).sum(axis=1)) data.loc[ismal,'extract_eff'] = (data[ismal].rmq_observation .str.extract('(\d+).00 Mâle\(s\) et \? Femelle\(s\)').astype(int).sum(axis=1)) data.loc[isfem,'extract_eff'] = (data[isfem].rmq_observation .str.extract('\? Mâle\(s\) et (\d+).00 Femelle\(s\)').astype(int).sum(axis=1)) extr = data.extract_eff.notna() extr_sup = data.effectif < data.extract_eff data[extr_sup] age_na = data.age_faune.isna() no_0 = data.extract_eff > 0 if any(age_na&no_0&ismixte): data.loc[age_na&no_0&ismixte,'age_faune'] = 'mixte' if any(age_na&no_0&ismal): data.loc[age_na&no_0&ismal,'age_faune'] = 'male' if any(age_na&no_0&isfem): data.loc[age_na&no_0&isfem,'age_faune'] = 'femelle' def form_date(data): cols = data.columns[data.columns.str.contains('date')] for col in cols: data.loc[data[col].isna(),col] = None def recup_stadevie(data): dict_repro = { 'ODO_Exuvie/émergence':'Exuvie/émergence', 'ODO_Immature':'Immature', **dict.fromkeys(['ODO_Mâles+Femelles','ODO_Tandem','ODO_Territorial','ODO_Ponte'],'Adulte'), **dict.fromkeys(['CHIR_Indéterminé','ODO_Indéterminé'],'Indéterminé') } if 'age_faune' in data.columns: age_isna = data.age_faune.isna() age_inrmq = data.rmq_observation.str.contains('Stade de vie') data.loc[age_isna&age_inrmq,'age_faune'] = (data[age_isna&age_inrmq].rmq_observation .str.split('Stade de vie :') .str[1] .str.split('|') .str[0] .str.strip()) double_info = data.age_faune.isin(['Imago, adulte', 'Nymphe, immature']) d2 = data[double_info].copy() data.age_faune = data.age_faune.str.replace('Imago, adulte','Imago') data.age_faune = data.age_faune.str.replace('Nymphe, immature','Nymphe') d2.age_faune = d2.age_faune.str.replace('Imago, adulte','Adulte') d2.age_faune = d2.age_faune.str.replace('Nymphe, immature','Immature') d2.id_obs = ('9999'+d2.id_obs.astype(str)).astype(int) data = gpd.pd.concat([data,d2]) lst_age = [*dict_repro.keys()] age_isna = data.age_faune.isna() t1 = age_isna&(data.reprostatut_faune.isin(lst_age)) data.loc[t1,'age_faune'] = data[t1].reprostatut_faune.replace(dict_repro) t2 = data.age_faune=='Exuvie/émergence' is_exuvie = (data.rmq_observation .replace(['é','E','É'],'e',regex=True) .str.contains('exuvie',na=False)) is_emerge = (data.rmq_observation .replace(['é','E','É'],'e',regex=True) .str.contains('emerge',na=False)) rmq_isna = data.rmq_observation.isna() data.loc[is_exuvie&~is_emerge&t2,'age_faune'] = 'Exuvie' data.loc[~is_exuvie&is_emerge&t2,'age_faune'] = 'Emergent' data.loc[is_exuvie&is_emerge&t2,'age_faune'] = 'Exuvie' data.loc[is_exuvie&is_emerge&rmq_isna&t2,'age_faune'] = 'Emergent' t3 = data.age_faune=='Oeuf/ponte/larve/nymphe/chenille...' # Odonate is_odo = data.ordre == 'Odonata' data.loc[t3&is_odo,'age_faune'] = 'Exuvie' # Amphibiens is_amphi = data.group2_inpn == 'Amphibiens' is_larve = data.rmq_observation.str.contains('larve',na=False) is_ponte = data.rmq_observation.str.contains('ponte|Ponte',na=False) is_tetar = data.rmq_observation.replace(['ê','é'],'e',regex=True).str.contains('tetard',na=False) is_urode = data.ordre=='Urodela' is_anure = data.ordre=='Anura' rmq_na = data.rmq_observation.isna() data.loc[t3&is_amphi&is_larve,'age_faune'] = 'Larve' data.loc[t3&is_amphi&is_ponte,'age_faune'] = 'Oeufs' data.loc[t3&is_amphi&is_tetar,'age_faune'] = 'Têtard' data.loc[t3&is_amphi&is_urode&rmq_na,'age_faune'] = 'Larve' data.loc[t3&is_amphi&is_anure&rmq_na,'age_faune'] = 'Ponte' # Corresction de 3 données de Nicolas Biron t3 = data.age_faune=='Oeuf/ponte/larve/nymphe/chenille...' data.loc[t3&(is_urode|is_anure),'age_faune'] = 'Ponte' # Correction de la dernière donnée restante (Marjorie Simean) t3 = data.age_faune=='Oeuf/ponte/larve/nymphe/chenille...' data.loc[t3,'age_faune'] = 'Oeufs' # Définition de l'objet du dénombrement si ponte if 'obj_denombre' not in data.columns: data['obj_denombre'] = None isnot_ponte = ~data.rmq_observation.str.contains('nbre pontes:0',na=False) data.loc[is_amphi&is_ponte&isnot_ponte,'obj_denombre'] = 'Ponte' # Récup stade_vie derrirère le terme @NSA age_isna = data.age_faune.isna() as_nsa = data.rmq_observation.str.contains('@NSA',na=False) # data.loc[age_isna&as_nsa,'test'] = (data[age_isna&as_nsa].rmq_observation # .str.split('@NSA :|@NSA:') # .str[1] # .str.split('/|;') # .str[0] # .str.strip()) data.loc[age_isna&as_nsa,'age_faune'] = (data[age_isna&as_nsa].rmq_observation .str.split('@NSA :|@NSA:') .str[1] .str.split('/|;') .str[0] .str.strip() .str.lower() .str.extract('(imm|juv|ad|jeune|larve)')[0]) # Récup stade_vie derrirère le terme Commentaires age_isna = data.age_faune.isna() as_com = data.rmq_observation.str.contains('Commentaires : \\d',na=False) data.loc[age_isna&as_com,'age_faune'] = (data[age_isna&as_com].rmq_observation .str.split('[,(.]|Code Atlas') .str[0].str.strip() .str.lower() .replace( {'femelles':'femelle','mâles':'mâle','adultes':'adulte', 'jeunes':'jeune','juvéniles':'juvénile','larves':'larve', 'couples':'couple','x':''},regex=True) .str.extract('[Commentaires : \d+ ](jeune volant|juvénile|juv|couple|adulte|ad|crapelet|femelle adulte|larve|mâle juvénile|mâle adulte|subadulte|larve \/ têtard)$')[0]) age_isna = data.age_faune.isna() data.loc[age_isna&as_com,'age_faune'] = (data[age_isna&as_com].rmq_observation .str.split('[,(.]|Code Atlas') .str[0].str.strip() .str.lower() .replace( {'femelles':'femelle','mâles':'mâle','adultes':'adulte', 'jeunes':'jeune','juvéniles':'juvénile','larves':'larve', 'têtards':'têtard','couples':'couple','x':''},regex=True) .str.extract('[Commentaires : \d+](jeune volant|juvénile|juv|couple|adulte|ad|crapelet|femelle adulte|larve|mâle adulte|subadulte|larve / têtard)$')[0]) # Précision de larve / têtard is_impreci = data.age_faune=='larve / têtard' data.loc[is_impreci&is_anure,'age_faune'] = 'têtard' data.loc[is_impreci&is_urode,'age_faune'] = 'larve' data.age_faune = (data.age_faune .replace({ 'ad':'Adulte', 'Oeufs':'Oeuf', 'imm':'Immature', 'jeune':'Jeune', 'juv':'Juvénile', 'subadulte':'Sub-adulte', 'Subadulte':'Sub-adulte',}) .str.capitalize() ) sex_isna = data.sexe_faune.isna() is_male = data.age_faune.str.contains('Mâle',na=False) is_feml = data.age_faune.str.contains('Femelle',na=False) is_copl = data.age_faune.str.contains('Couple',na=False) is_immat = data.age_faune.str.contains('Immature',na=False) data.loc[sex_isna&is_male,'sexe_faune'] = 'Mâle' data.loc[sex_isna&is_feml,'sexe_faune'] = 'Femelle' data.loc[sex_isna&is_copl,'sexe_faune'] = 'Couple' data.loc[sex_isna&is_immat,'sexe_faune'] = 'Immature' return data def complete_objdenomb(data): asnot_denomb = data.obj_denombre.isna() isnot_dead = data.etat_bio != 'mort' as_statbio = data.statut_bio.notna() as_compt = data.comportement.notna() as_atlas = data.code_atlas.notna() as_age = data.age_faune.notna() as_sexe = data.sexe_faune.notna() as_repro = data.reprostatut_faune.notna() as_determ = data.determination.notna() data.loc[asnot_denomb&isnot_dead&(as_statbio|as_compt|as_atlas|as_age|as_sexe|as_repro|as_determ),'obj_denombre'] = 'individu' return data def recup_comptmt(data): if 'reprostatut_faune' in data.columns: # Récupération du comportement après `Comp. ind` dans la colonne `rmq_observation` compt_isna = data.reprostatut_faune.isna() in_rmq = data.rmq_observation.str.contains('Comp. ind') data.loc[compt_isna&in_rmq,'comportement'] = (data[compt_isna&in_rmq].rmq_observation .str.split('Comp. ind. :') .str[1] .str.split('|') .str[0] .str.strip()) # Récupération du comportement dans la colonne `reprostatut_faune` sex_isna = data.sexe_faune.isna() comp_isna = data.comportement.isna() lst_comp_inv = [ 'ODO_Tandem','ODO_Territorial','INV_Accouplement','INV_Chant (orthoptères)','ODO_Ponte'] lst_comp_ver = ['OIS_Reproduction certaine (patrim)','MAM_Fécès - épreinte - urine', 'OIS_Nid avec jeune(s)', 'OIS_Couvaison', 'CHIR_Hivernant', 'AMP_Mise bas - ponte','CHIR_Lethargie', 'OIS_Chant', # 'AMP_Indéterminé', 'AMP_Chant','CHIR_Estivant', 'CHIR_Transit', 'OIS_Reproduction possible', 'MAM_Alarme', 'AMP_Accouplement', 'OIS_Fuite - envol','OIS_Accouplement'] if data.reprostatut_faune.isin(lst_comp_inv).any(): t3 = (~compt_isna)&comp_isna&sex_isna&(data.reprostatut_faune.isin(lst_comp_inv)) elif data.reprostatut_faune.isin(lst_comp_ver).any(): t3 = (~compt_isna)&comp_isna&(data.reprostatut_faune.isin(lst_comp_ver)) data.loc[t3,'comportement'] = data[t3].reprostatut_faune # Récupération du comportement après `Comp. ind` dans la colonne `rmq_observation` # dictionnaire des transports dict_transport = { **dict.fromkeys(['transport de branche','transport de matériaux','transport de brindille','transporte une branche',"transport d'une branche",'transportant des matériaux','transportant une branche','transporte des feuilles'],'transport matériaux'), **dict.fromkeys(['transport de nourriture','transport nourriture','transport de poisson','transportant nourriture','Transporte une proie','transport de proie'],'transport nourriture'), } lst_rmq_comp = "chant|houspille|en chasse|{}|en vol|en survol|posé|parade|s'envole|se nourrit|se pose|tambourinage|vol migratoire|hivernage|nourrissage|couveur|nourrit|cht|cris|estivant|hivernant|Construction de nid|alarme|migration active".format('|'.join(dict_transport.keys())) comp_isna = data.comportement.isna() in_rmq = data.rmq_observation.str.contains('[%s]'%lst_rmq_comp,case=False,na=False) data.loc[comp_isna&in_rmq,'comportement'] = (data[comp_isna&in_rmq].rmq_observation .str.lower() .str.extract('(%s)'%lst_rmq_comp)[0] .replace(dict_transport)) comp_isna = data.comportement.isna() envol = data.rmq_observation.str.contains('Statut:Passage.') if any(comp_isna&envol): data.loc[comp_isna&envol,'comportement'] = 'en vol' comp_isna = data.comportement.isna() data.loc[comp_isna,'comportement'] = (data[comp_isna].rmq_observation .replace({'x',''},regex=True) .str.lower() .str.extract('[détails : \d+ ]\((en transit)\)')[0]) def _get_gn_atlas(): sch = 'ref_nomenclatures' tab = ['t_nomenclatures','bib_nomenclatures_types'] bib_mnemo='CODE_ATLAS' sql = """ SELECT a.id_nomenclature, a.cd_nomenclature, a.mnemonique mnemo, a.label_default as label, a.label_fr, a.definition_default definition, a.definition_fr def_fr, b.mnemonique bib_mnemo, b.label_default bib_label, b.definition_default bib_def, a.active FROM {sch}.{tab0} a JOIN {sch}.{tab1} b USING (id_type) """.format(sch=sch,tab0=tab[0],tab1=tab[1]) if bib_mnemo is not None: sql += " WHERE " sql += "b.mnemonique = '%s'"%bib_mnemo return gpd.pd.read_sql_query(sql,con_gn) def recup_atlas(data): is_atlas = data.rmq_observation.str.contains('Code atlas',na=False) # is_atlas = data.rmq_observation.str.contains('Code atlas :',na=False) if any(is_atlas): atlas = _get_gn_atlas() dict_code = dict(zip(atlas.cd_nomenclature.astype(int).astype(str),atlas.label_fr)) dict_label = dict(zip(atlas.label.str.removesuffix('.'),atlas.label_fr)) dict_autre = { 'Mâle chanteur (ou cris de nidification) ou tambourinage en période de reproduction':'Mâle chanteur présent en période de nidification, cris nuptiaux ou tambourinage entendus, mâle vu en parade', 'Jeunes fraîchement envolés (espèces nidicoles) ou poussins (espèces nidifuges)':'Jeunes en duvet ou jeunes venant de quitter le nid et incapables de soutenir le vol sur de longues distances' } data.loc[is_atlas,'code_atlas'] = (data[is_atlas].rmq_observation .str.split('Code atlas') .str[1] # .str.split('\||@|;|\(') .str.split(r'[|@;]') .str[0] .replace({ **dict.fromkeys([':','Nidification possible \(','Nidification certaine \(','Nidification probable \('],''), '\s+':' ', ' - ':'; '},regex=True) .str.strip() .str.replace('nuptial parades','nuptial: parades') .str.removesuffix(')') .replace('',None) .replace(dict_code) .replace(dict_autre) .replace(dict_label)) data.loc[is_atlas,'rmq1'] = (data[is_atlas].rmq_observation .str.split('Code atlas') .str[0] .str.strip() .replace(dict.fromkeys(['Commentaires :','Remarques :','Détails : @','','nan'],None)) ) data.loc[is_atlas,'rmq2'] = (data[is_atlas].rmq_observation .str.split('Code atlas') .str[1] .str.split(r'[|@;]') .str[1] .str.strip() .str.removesuffix(';') .str.strip() .replace(dict.fromkeys(['','nan'],None)) ) data.loc[is_atlas,'rmq_observation'] = [ ' ; '.join([x,y]) if not gpd.pd.isna(y) and not gpd.pd.isna(x) else y if gpd.pd.isna(x) else x for x,y in zip(data[is_atlas].rmq1,data[is_atlas].rmq2) ] data.rmq_observation.replace('nan',None,inplace=True) data.drop(columns=['rmq1','rmq2'],inplace=True) atlas_isna = data.code_atlas.isna() rmq_atlas = { '2':"Observation de l'espèce pendant la période de nidification dans un biotope adéquat", '2':"Observation de l'espèce pendant la période de nidification", '4':'Couple pendant la période de nidification dans un biotope adéquat', } for k,v in rmq_atlas.items(): as_atlas = data.rmq_observation.str.contains(v,na=False) data.loc[atlas_isna&as_atlas,'code_atlas'] = dict_code[k] # Récupération du code atlas 99 for i in ['99','1.00','2','3.00','3 ','4 ','4.00','5.00','5 ', '6','7','8','9.00','9 ','10','11 ','12 ','12.00','13', '14.00','14 ','15.00','16','17','18','19']: is_atlas = data.rmq_observation.str.contains('Code Atlas : %s'%i,na=False) atlas_isna = data.code_atlas.isna() if is_atlas.any(): data.loc[is_atlas&atlas_isna,'code_atlas'] = str(int(float('%s'%i))) data.loc[is_atlas&atlas_isna,'code_atlas'] = data[is_atlas&atlas_isna].code_atlas.replace(dict_code) # définition du code_atlas par le statut repro lst_repro = [ 'Reproduction possible','Reproduction probable','Reproduction confirmée','Nicheur possible' ] atlas_isna = data.code_atlas.isna() is_aves = data.group2_inpn == 'Oiseaux' is_repro = data.statut_bio.isin(lst_repro) if any(is_aves&is_repro&atlas_isna): data.loc[is_aves&is_repro&atlas_isna,'code_atlas'] = (data[is_aves&is_repro&atlas_isna].statut_bio .replace(['Reproduction','Nicheur'],'Nidification') .replace(dict_label)) # définition du code atlas par le statut repro atlas_isna = data.code_atlas.isna() dict_repro = { **dict.fromkeys(['couvaison','couveur','ois_couvaison'],'18'), **dict.fromkeys(['accouplement','ois_accouplement','parade'],'6'), **dict.fromkeys(['alarme'],'8'), **dict.fromkeys(['chant','cht','ois_chant'],'3'), **dict.fromkeys(['nourrissage','nourrissage des jeunes'],'16'), **dict.fromkeys(['ois_nid avec jeune(s)'],'19'), **dict.fromkeys(['ois_reproduction certaine (patrim)'],'50'), **dict.fromkeys(['ois_reproduction possible'],'30'), **dict.fromkeys(['transport matériaux'],'10'), } for k,v in dict_repro.items(): is_repro = data.comportement.str.lower()==k if any(is_repro&atlas_isna): data.loc[is_repro&is_aves&atlas_isna,'code_atlas'] = dict_code[v] # Suppression des codes atlas érronés is_dead = data.etat_bio=='mort' atlas_notna = data.code_atlas.notna() if any(is_dead&atlas_notna): data.loc[is_dead&atlas_notna,'code_atlas'] = None def form_observator(data): return data.observateurs_v2.replace({ ' \(CEN Isère\) \(CEN Isère\)':'', ' \(GRPLS\) \(GRPLS\)':'', ' \(CD Isère\) \(CD Isère\)':'', ' \(BIOTOPE\) \(BIOTOPE\)':'', ' \(Ecosphère\) \(Ecosphère\)':'', ' \(FMBDS\) \(FMBDS\)':'', ' \(Lo Parvi\) \(Lo Parvi\)':'', ' \(LPO Rhône\) \(LPO Rhône\)':'', ' \(Personnel\) \(Personnel\)':'', ' \(ONCFS\) \(ONCFS\)':'', ' \(Nature et Vie Sociale\) \(Nature et Vie Sociale\)':'', ' \(Conservatoire d’Espaces Naturels Isère\) \(Conservatoire d’Espaces Naturels Isère\)':'', ' \(Société Batrachologique de France\) \(Société Batrachologique de France\)':'', 'CEN Isère':'Conservatoire d’Espaces Naturels Isère', },regex=True) def form_coord(data): t1 = data.longitude_x > 10 t2 = data.latitude_y > 50 data.loc[t1,'longitude_x'] = data[t1].to_crs(epsg=4326).geom.x data.loc[t2,'latitude_y'] = data[t2].to_crs(epsg=4326).geom.y def form_rmqobs(data): data.rmq_observation.replace({ 'Commentaires : Détails :':'Détails :', 'Commentaires : , localisation :':'localisation :', },inplace=True,regex=True) def recup_determ(data): determ_isna = data.determination.isna() is_statut = data.rmq_observation.str.contains('Indice de présence') if is_statut.any(): data.loc[determ_isna&is_statut,'determination'] = 'Indice de présence' data.loc[determ_isna&is_statut,'preuve_detrm'] = (data[determ_isna&is_statut].rmq_observation .str.split('Indice de présence') .str[1] .str.split('|') .str[0] .str.strip() .str.extract('.*\((.*)\).*')[0] ) determ_isna = data.determination.isna() data.loc[determ_isna,'determination'] = (data[determ_isna].rmq_observation .str.extract('.*\((en main|observation indirecte|vu|contact auditif|analyse de pelotes)\).*')[0] ) # determ_isna = data.determination.isna() # in_hand = data.rmq_observation.str.contains('\(en main\)') # if any(determ_isna&in_hand): # data.loc[determ_isna&in_hand,'determination'] = 'en main' determ_isna = data.determination.isna() vu = data.rmq_observation.str.contains('Individu vu|Vu vivant|Commentaires \: Vu') if any(determ_isna&vu): data.loc[determ_isna&vu,'determination'] = 'Individu vu' determ_isna = data.determination.isna() entendu = data.rmq_observation.str.contains('Individu entendu') if any(determ_isna&entendu): data.loc[determ_isna&entendu,'determination'] = 'Individu entendu' determ_isna = data.determination.isna() photo = data.rmq_observation.str.contains('piège photo') if any(determ_isna&photo): data.loc[determ_isna&photo,'determination'] = 'Observation par piège photographique' def recup_statutbio(data): data['statut_bio'] = None is_stat1 = data.rmq_observation.str.contains('Caractéristique',na=False) if is_stat1.any(): statbio_isna = data.statut_bio.isna() data.loc[statbio_isna&is_stat1,'statut_bio'] = (data[statbio_isna&is_stat1].rmq_observation .str.split('Caractéristique :') .str[1] .str.split('\|') .str[0] .str.strip() ) is_stat2 = data.rmq_observation.str.contains('Statut',na=False) if is_stat2.any(): statbio_isna = data.statut_bio.isna() data.loc[statbio_isna&is_stat2,'statut_bio'] = (data[statbio_isna&is_stat2].rmq_observation .str.split('Statut') .str[1] .str.strip() .str.removeprefix(':').str.strip() .str.split('\||/|;') .str[0] .str.strip() .str.extract('(Migrateur|Estivage|Reproduction probable|Reproduction certaine|Reproduction possible|Hivernant)')[0] ) is_stat3 = data.rmq_observation.str.contains('Critere',na=False) if is_stat3.any(): statbio_isna = data.statut_bio.isna() data.loc[statbio_isna&is_stat3,'statut_bio'] = (data[statbio_isna&is_stat3].rmq_observation .str.split('Critere') .str[1] .str.strip() .str.removeprefix(':').str.strip() .str.split('\||/|;') .str[0] .str.strip() .str.extract('(nicheurs possibles|reproducteur)')[0] ) is_stat4 = data.rmq_observation.str.contains('Commentaires',na=False) if is_stat4.any(): statbio_isna = data.statut_bio.isna() data.loc[statbio_isna&is_stat4,'statut_bio'] = (data[statbio_isna&is_stat4].rmq_observation .str.split('Commentaires') .str[1] .str.strip() .str.removeprefix(':').str.strip() .str.lower() .str.extract('(estivant|nicheur certain|nicheur probable|nicheur|semble nicher|niche|Reproduction probable|Reproduction certaine|Reproduction possible)')[0] ) def recup_etatbio(data): data['etat_bio'] = None # Récupération de la mortalité dans le champs rmq_observation is_dead1 = (data.rmq_observation .str.lower() .str.contains('individu mort|trouvé mort|mort : oui',na=False)) if is_dead1.any(): data.loc[is_dead1,'etat_bio'] = 'mort' is_dead2 = data.comportement.str.lower()=='cadavre' if is_dead2.any(): data.loc[is_dead2,'etat_bio'] = 'mort' # nettoyage des comportements si individu mort is_dead = is_dead1|is_dead2 compt_notna = data.comportement.notna() if any(is_dead&compt_notna): data.loc[is_dead&compt_notna,'comportement'] = None # adaptation de la détermination detm_hand = data.determination=='en main' if any(detm_hand&is_dead): data.loc[detm_hand&is_dead,'comportement'] = 'cadavre en main' def recup_sexefaune(data): is_male = data.rmq_observation.replace({'[x.0s]':''},regex=True).str.lower().str.contains('\\d mâle',na=False) is_feml = data.rmq_observation.replace({'[x.0s]':''},regex=True).str.lower().str.contains('\\d femelle',na=False) sexe_isna = data.sexe_faune.isna() data.loc[sexe_isna&is_male&~is_feml,'sexe_faune'] = 'mâle' data.loc[sexe_isna&~is_male&is_feml,'sexe_faune'] = 'femelle' data.loc[sexe_isna&is_male&is_feml,'sexe_faune'] = 'mixte' def format_faune(data): recup_sexefaune(data) recup_comptmt(data) recup_etatbio(data) recup_statutbio(data) recup_atlas(data) res = recup_stadevie(data) return complete_objdenomb(res) def format_data(data): form_rmqobs(data) data.observateurs_v2 = form_observator(data) form_precision(data) form_effectif(data) correct_taxonomie(data) form_cdnom(data) form_date(data) form_coord(data) form_complx_grp(data) recup_determ(data) return format_faune(data) def _export(path_name, data, format='csv'): if format=='xlsx': data.to_excel(path_name+'.%s'%format) elif format=='csv': data.to_csv(path_name+'.%s'%format) else: raise('format non prévu') def _filter_diffusable(path_name,data): if any(data.diffusable=='non'): no_diff = data[data.diffusable=='non'].copy() diff = data[data.diffusable=='oui'].copy() to_export = { path_name+'_diff':diff, path_name+'_no_diff':no_diff } else: to_export = { path_name:data } return to_export def _filter_uuid_sinp(to_export): res = {} for k,v in to_export.items(): if 'unique_id_sinp' in v.columns: uuid_sinp = v[v.unique_id_sinp.notna()] not_uuid = v[v.unique_id_sinp.isna()] res |= { k+'_uuid':uuid_sinp, k+'_not_uuid':not_uuid } else: res |= { k:v } return res def export(path_name, data, format='csv'): # Formatage des dates avant écriture detect_date = data.columns[data.columns.str.startswith('date')] data.loc[:,detect_date] = data[detect_date].astype(str) # Suppression de la colonne geom df = data.to_wkt().drop(columns='geom',errors='ignore') # Export _to_export = _filter_diffusable(path_name,df) to_export = _filter_uuid_sinp(_to_export) for k,v in to_export.items(): if v.empty: continue _export(k,v,format) def serena_rnngl_site(): from sqlalchemy import create_engine # pour lecture de la bd from sqlalchemy.engine import URL from shapely.geometry import Polygon usr = 'postgres' pdw = 'postgres' bdd = 'serenadb' host = '172.17.0.2' eng = URL.create('postgresql+psycopg2',username=usr,password=pdw,host=host,database=bdd) conn = create_engine(eng) sit = gpd.pd.read_sql_table('rnf_site',con=conn,schema='serenabase') sit['poly'] = (sit .site_poly.str[9:] .str.split(',')) sit.loc[sit.poly.notna(),'geom'] = (sit.loc[sit.poly.notna(),'poly'] .apply(lambda x: [xx.split(' ') for xx in x if xx]) .apply(lambda x: [[float(xxx) for xxx in xx] for xx in x ]) .apply(lambda x: Polygon(x))) return (sit .set_geometry('geom',crs=4326) .to_crs(2154) .dropna(subset=['geom'])) if __name__ == "__main__": v_synthese_invertebre = 'v_synthese_invertebre' v_synthese_vertebre = 'v_synthese_vertebre' v_synthese_flore = 'v_synthese_flore' sit_rnngl = serena_rnngl_site() # sql_exclude_rnngl = " (rmq_localisation NOT ILIKE '%%lemps%%' OR NOT ST_INTERSECTS(geom,'SRID=2154;{}'))".format(sit_rnngl.unary_union) sql_exclude_rnngl = " rmq_localisation NOT ILIKE '%%grand%%lemps%%'" sql_rmqloc_null = " rmq_localisation IS NULL" sql_inv = "SELECT * FROM saisie.%s WHERE cd_nom <> '9999081'"%v_synthese_invertebre # 9999081 : Heterocera sp. v_inv = gpd.read_postgis(sql_inv+" AND"+sql_exclude_rnngl,con_sicen).dropna(how='all',axis=1) v_inv_autre = gpd.read_postgis(sql_inv+" AND"+sql_rmqloc_null,con_sicen).dropna(how='all',axis=1) v_inv = gpd.pd.concat([v_inv,v_inv_autre],ignore_index=True).reset_index(drop=True) v_inv_rnngl = gpd.read_postgis(sql_inv+" AND"+sql_exclude_rnngl.replace('NOT ',''),con_sicen).dropna(how='all',axis=1) t1_inv = v_inv_rnngl.etude.str.contains('Haute Bourbre 2014') t2_inv = v_inv_rnngl.observateurs_v2.isin(['ZARADZKI Lise (CEN Isère)','BIRON Nicolas (CEN Isère)']) t3_inv = v_inv.observateurs_v2=='LUCAS Jérémie (CEN Isère)' t4_inv = v_inv.etude!='Echange de données - GRPLS' hb_inv = v_inv_rnngl[t1_inv|t2_inv].copy() no_stg = v_inv[t3_inv&t4_inv].copy() v_inv = gpd.pd.concat([v_inv,hb_inv],ignore_index=True).drop_duplicates() v_inv_rnngl.drop(hb_inv.index,inplace=True) v_inv_rnngl = gpd.pd.concat([v_inv_rnngl,no_stg],ignore_index=True).drop_duplicates() v_inv.drop(no_stg.index,inplace=True) #v_synthese_invertebre = 37915 #v_inv.shape[0]+v_inv_rnngl.shape[0] = 37914 #différence de 1 donnée. Correspond au taxon 9999081 dans la bdd sql_ver = "SELECT * FROM saisie.%s WHERE cd_nom <> '9999056'"%v_synthese_vertebre # 9999056 : Micromammalia sp. (17 données) v_ver = gpd.read_postgis(sql_ver+" AND"+sql_exclude_rnngl,con_sicen).dropna(how='all',axis=1) v_ver_autre = gpd.read_postgis(sql_ver+" AND"+sql_rmqloc_null,con_sicen).dropna(how='all',axis=1) v_ver = gpd.pd.concat([v_ver,v_ver_autre],ignore_index=True).reset_index(drop=True) v_ver_rnngl = gpd.read_postgis(sql_ver+" AND"+sql_exclude_rnngl.replace('NOT ',''),con_sicen).dropna(how='all',axis=1) t1_ver = v_ver_rnngl.etude.str.contains('Haute Bourbre 2014') t2_ver = v_ver_rnngl.observateurs_v2.isin(['ZARADZKI Lise (CEN Isère)','BIRON Nicolas (CEN Isère)']) t3_ver = v_ver.observateurs_v2.isin(['LUCAS Jérémie (CEN Isère)','PRUNIER Jérôme (Personnel)', 'MAILLET Grégory (CEN Isère)','LAFON Arnaud (CEN Isère)']) t4_ver = v_ver.etude!='Echange de données - GRPLS' hb_ver = v_ver_rnngl[t1_ver|t2_ver].copy() sg_ver = v_ver[t3_ver&t4_ver].copy() v_ver = gpd.pd.concat([v_ver,hb_ver],ignore_index=True).drop_duplicates() v_ver_rnngl.drop(hb_ver.index,inplace=True) v_ver_rnngl = gpd.pd.concat([v_ver_rnngl,sg_ver],ignore_index=True).drop_duplicates() v_ver.drop(sg_ver.index,inplace=True) #v_synthese_vertebre = 102175 #v_ver.shape[0]+v_ver_rnngl.shape[0] = 102158 #différence de 17 donnée. Correspond au taxon 9999056 dans la bdd sql_flo = 'SELECT * FROM saisie.%s'%v_synthese_flore v_flo = gpd.read_postgis(sql_flo+" WHERE"+sql_exclude_rnngl,con_sicen).dropna(how='all',axis=1) v_flo_autre = gpd.read_postgis(sql_flo+" AND"+sql_rmqloc_null,con_sicen).dropna(how='all',axis=1) v_flo = gpd.pd.concat([v_flo,v_flo_autre],ignore_index=True).reset_index(drop=True) v_flo_rnngl = gpd.read_postgis(sql_flo+" WHERE"+sql_exclude_rnngl.replace('NOT ',''),con_sicen).dropna(how='all',axis=1) t1_flo = v_flo_rnngl.etude.str.contains('Haute Bourbre 2014') t2_flo = v_flo_rnngl.observateurs_v2=='ZARADZKI Lise (CEN Isère)' t3_flo = v_flo.observateurs_v2=='LUCAS Jérémie (CEN Isère)' t4_flo = v_flo.etude!='Echange de données - GRPLS' hb_flo = v_flo_rnngl[t1_flo|t2_flo].copy() sg_flo = v_flo[t3_flo&t4_flo].copy() v_flo = gpd.pd.concat([v_flo,hb_flo],ignore_index=True).drop_duplicates() v_flo_rnngl.drop(hb_flo.index,inplace=True) idflo_drop = v_flo[v_flo.id_obs.isin(v_flo_rnngl.id_obs)].index v_flo.drop(idflo_drop,inplace=True) v_flo_rnngl = gpd.pd.concat([v_flo_rnngl,sg_flo],ignore_index=True).drop_duplicates() v_flo.drop(sg_flo.index,inplace=True) #v_synthese_flore = 113556 #v_flo.shape[0]+v_flo_rnngl.shape[0] = 113556 v_inv_explode = format_data(v_inv) V_VER = v_ver.copy() v_ver = V_VER.copy() v_ver_explode = format_data(v_ver) format_data(v_flo) inv_uuid = (gpd.pd.read_csv(os.path.join(DIR,'INVERTEBRE/','ORB_UUID','donnees_importees_cen38.csv'),sep=';') .rename(columns={'entity_source_pk_value':'id_obs'})) v_inv_explode = v_inv_explode.merge(inv_uuid[['id_obs', 'unique_id_sinp']],how='left',on='id_obs') # list_inv = v_inv_explode[v_inv_explode.unique_id_sinp.notna()].etude.unique() # INVERTEBRE for etude in v_inv_explode.etude.unique(): exp_inv = v_inv_explode[v_inv_explode.etude==etude].copy() exp_inv.dropna(how='all',inplace=True,axis=1) if 'complexe_groupe' in exp_inv.columns: exp_inv1 = exp_inv[exp_inv.complexe_groupe.notna()] exp_inv2 = exp_inv[exp_inv.complexe_groupe.isna()].dropna(how='all',axis=1) export(os.path.join(DIR,'INVERTEBRE','INV_'+etude+'_GRP'),exp_inv1,format='csv') export(os.path.join(DIR,'INVERTEBRE','INV_'+etude),exp_inv2,format='csv') else : export(os.path.join(DIR,'INVERTEBRE','INV_'+etude),exp_inv,format='csv') # VERTEBRE for etude in v_ver_explode.etude.unique(): exp_ver = v_ver_explode[v_ver_explode.etude==etude].copy() exp_ver.dropna(how='all',inplace=True,axis=1) if 'complexe_groupe' in exp_ver.columns: exp_ver1 = exp_ver[exp_ver.complexe_groupe.notna()] exp_ver2 = exp_ver[exp_ver.complexe_groupe.isna()].dropna(how='all',axis=1) export(os.path.join(DIR,'VERTEBRE','VER_'+etude+'_GRP'),exp_ver1,format='csv') export(os.path.join(DIR,'VERTEBRE','VER_'+etude),exp_ver2,format='csv') else : export(os.path.join(DIR,'VERTEBRE','VER_'+etude),exp_ver,format='csv') # FLORE for etude in v_flo.etude.unique(): exp_flo = v_flo[v_flo.etude==etude].copy() exp_flo.dropna(how='all',inplace=True,axis=1) if 'complexe_groupe' in exp_flo.columns: exp_flo1 = exp_flo[exp_flo.complexe_groupe.notna()] exp_flo2 = exp_flo[exp_flo.complexe_groupe.isna()].dropna(how='all',axis=1) export(os.path.join(DIR,'FLORE','FLO_'+etude+'_locNULL'+'_GRP'),exp_flo1,format='csv') export(os.path.join(DIR,'FLORE','FLO_'+etude+'_locNULL'),exp_flo2,format='csv') else : export(os.path.join(DIR,'FLORE','FLO_'+etude+'_locNULL'),exp_flo,format='csv') # _export(os.path.join(DIR,v_synthese_invertebre+'2'),v_inv_explode.dropna(how='all',axis=1)) # _export(os.path.join(DIR,v_synthese_invertebre),v_inv.dropna(how='all',axis=1)) # _export(os.path.join(DIR,v_synthese_vertebre+'2'),v_ver_explode.dropna(how='all',axis=1)) # _export(os.path.join(DIR,v_synthese_vertebre),v_ver.dropna(how='all',axis=1)) # _export(os.path.join(DIR,v_synthese_flore),v_flo) # v_ver.etude.unique() # v_ver.protocole.unique() # v_ver.lot_donnee.unique()