2024-06-11 10:13:03 +02:00

861 lines
39 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 dEspaces Naturels Isère\) \(Conservatoire dEspaces Naturels Isère\)':'',
' \(Société Batrachologique de France\) \(Société Batrachologique de France\)':'',
'CEN Isère':'Conservatoire dEspaces 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+" WHERE"+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_rnngl = gpd.pd.concat([v_ver_rnngl,v_flo_rnngl,v_inv_rnngl],ignore_index=True)
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()