Source code for palangre_syc.excel_extractions

""" 

Module de fonctions qui permettent l'extraction des données de logbook palangre 
selon le format utilisé par les Seychelles

"""
import pandas as pd
import numpy as np
import re

from django.utils.translation import gettext as _

from api_traitement import common_functions

[docs] def extract_vessel_info(df_donnees): """ Extraction des cases 'Vessel Information' Args: df_donnees (df): excel p1 Returns: df """ df_vessel = df_donnees.iloc[7:16, 0] # On sépare en deux colonnes selon ce qu'il y a avant et après les ':' df_vessel_clean = df_vessel.str.split(':', expand=True) # S'assurer que toutes les valeurs sont des chaînes de caractères df_vessel_clean = df_vessel_clean.map(lambda x: str(x).strip() if x is not None else '') df_vessel_clean.columns = ['Logbook_name', 'Value'] # On enlève les caractères spéciaux df_vessel_clean['Logbook_name'] = common_functions.remove_spec_char_from_list(df_vessel_clean['Logbook_name']) df_vessel_clean['Logbook_name'] = df_vessel_clean['Logbook_name'].apply(lambda x: str(x).strip() if x is not None else '') return df_vessel_clean
[docs] def extract_cruise_info(df_donnees): """ Extraction des cases 'Cruise Information' Args: df_donnees (df): excel p1 Returns: df """ # On extrait les données propres au 'Cruise information' df_cruise1 = df_donnees.iloc[9:10, 11:20] df_cruise2 = df_donnees.iloc[9:10, 20:29] # On supprimes les colonnes qui sont vides df_cruise1 = common_functions.del_empty_col(df_cruise1) df_cruise2 = common_functions.del_empty_col(df_cruise2) np_cruise = np.append(np.array(df_cruise1), np.array(df_cruise2), axis=0) # on nettoie la colonne en enlevant les espaces et les ':' np_cruise[:, 0] = common_functions.np_removing_semicolon(np_cruise, 0) # On applique la fonction strip sur les cellules de la colonnes Valeur, # si l'élément correspond à une zone de texte vect = np.vectorize(common_functions.strip_if_string) np_cruise[:, 1] = vect(np_cruise[:, 1]) df_cruise = pd.DataFrame(np_cruise, columns=['Logbook_name', 'Value']) # Nettoyer la colonne 'Logbook_name' en enlevant les espaces et les ':' df_cruise['Logbook_name'] = df_cruise.iloc[:, 0].str.replace(':', '').str.strip() # Appliquer la fonction strip sur les cellules de la colonne 'Value' si l'élément correspond à une zone de texte df_cruise['Value'] = df_cruise.iloc[:, 1].apply(lambda x: x.strip() if isinstance(x, str) else x) # Appliquer un filtre pour les caractères spéciaux dans la colonne 'Logbook_name' et 'Value' df_cruise['Logbook_name'] = common_functions.remove_spec_char_from_list(df_cruise['Logbook_name']) df_cruise['Value'] = common_functions.remove_spec_char_from_list(df_cruise['Value']) # Supprimer les espaces supplémentaires dans la colonne 'Logbook_name' df_cruise['Logbook_name'] = df_cruise['Logbook_name'].str.strip() return df_cruise
[docs] def extract_report_info(df_donnees): """ Extraction des cases 'Report Information' Args: df_donnees (df): excel p1 Returns: df """ # On extrait les données df_report = df_donnees.iloc[7:9, 29:35] # On supprime les colonnes qui sont vides df_report = df_report.dropna(axis=1, how='all') # Nettoyer la colonne 'Logbook_name' en enlevant les espaces et les ':' df_report.iloc[:, 0] = df_report.iloc[:, 0].str.replace(':', '').str.strip() # Nettoyer la colonne 'Value' en appliquant strip() si l'élément correspond à une chaîne de caractères df_report.iloc[:, 1] = df_report.iloc[:, 1].apply(lambda x: x.strip() if isinstance(x, str) else x) # Renommer les colonnes df_report.columns = ['Logbook_name', 'Value'] # Appliquer un filtre pour les caractères spéciaux dans la colonne 'Logbook_name' df_report['Logbook_name'] = common_functions.remove_spec_char_from_list(df_report['Logbook_name']) # Supprimer les espaces supplémentaires dans la colonne 'Logbook_name' df_report['Logbook_name'] = df_report['Logbook_name'].str.strip() return df_report
[docs] def extract_gear_info(df_donnees): """ Extraction des cases 'Gear' Args: df_donnees (df): excel p1 Returns: df """ # On extrait les données df_gear = df_donnees.iloc[12:16, 11:21] # On supprimes les colonnes qui sont vides df_gear = common_functions.del_empty_col(df_gear) # Nettoyer la colonne 'Logbook_name' en enlevant les espaces et les ':' df_gear.iloc[:, 0] = df_gear.iloc[:, 0].str.replace(':', '').str.strip() # Nettoyer la colonne 'Value' en appliquant strip() si l'élément correspond à une chaîne de caractères df_gear.iloc[:, 1] = df_gear.iloc[:, 1].apply(lambda x: x.strip() if isinstance(x, str) else x) # Renommer les colonnes df_gear.columns = ['Logbook_name', 'Value'] # Appliquer un filtre pour les caractères spéciaux dans la colonne 'Logbook_name' df_gear['Logbook_name'] = common_functions.remove_spec_char_from_list(df_gear['Logbook_name']) # Supprimer les espaces supplémentaires dans la colonne 'Logbook_name' df_gear['Logbook_name'] = df_gear['Logbook_name'].str.strip() # On vérifie que les données du excel sont des entiers toutes_int = df_gear['Value'].apply(lambda cellule: isinstance(cellule, int)).all() if toutes_int: # Applique la fonction vect si toutes les cellules sont des entiers df_gear['Value'] = np.vectorize(common_functions.strip_if_string)(df_gear['Value']) if not df_gear['Value'].apply(lambda x: isinstance(x, int)).all(): message = _("Les données remplies dans le fichier soumis ne correspondent pas au type de données attendues. Ici on attend seulement des entiers.") return df_gear, message return df_gear
[docs] def extract_line_material(df_donnees): """ Extraction des cases 'Gear' Args: df_donnees (df): excel p1 Returns: df """ # On extrait les données df_line = df_donnees.iloc[12:16, 21:29] # On supprimes les colonnes qui sont vides df_line = common_functions.del_empty_col(df_line) # Nettoyer la colonne 'Logbook_name' en enlevant les espaces et les ':' df_line.iloc[:, 0] = df_line.iloc[:, 0].str.replace(':', '').str.strip() # Nettoyer la colonne 'Value' en appliquant strip() si l'élément correspond à une chaîne de caractères df_line.iloc[:, 1] = df_line.iloc[:, 1].apply(lambda x: x.strip() if isinstance(x, str) else x) # Renommer les colonnes df_line.columns = ['Logbook_name', 'Value'] # Appliquer un filtre pour les caractères spéciaux dans la colonne 'Logbook_name' df_line['Logbook_name'] = common_functions.remove_spec_char_from_list(df_line['Logbook_name']) # Supprimer les espaces supplémentaires dans la colonne 'Logbook_name' df_line['Logbook_name'] = df_line['Logbook_name'].str.strip() df_line['Value'] = df_line['Value'].str.strip() # Filtrer les lignes qui sont cochées df_line_used = df_line[(df_line["Value"] != "None") & (df_line["Value"].notna())] if len(df_line_used) > 1: message = _("Ici on n'attend qu'un seul matériau. Veuillez vérifier les données.") return df_line_used if len(df_line_used) == 0: message = _("La table entre les lignes 13 à 16 de la colonne 'AC' ne sont pas saisies. Veuillez vérifier les données.") return df_line_used, message return df_line_used
[docs] def extract_target_species(df_donnees): """ Extraction des cases 'Target species' Args: df_donnees (df): excel p1 Returns: df """ # On extrait les données df_target = df_donnees.iloc[12:16, 29:34] # On supprimes les colonnes qui sont vides df_target = common_functions.del_empty_col(df_target) # Nettoyer la colonne 'Logbook_name' en enlevant les espaces et les ':' df_target.iloc[:, 0] = df_target.iloc[:, 0].str.replace(':', '').str.strip() # Nettoyer la colonne 'Value' en appliquant strip() si l'élément correspond à une chaîne de caractères df_target.iloc[:, 1] = df_target.iloc[:, 1].apply(lambda x: x.strip() if isinstance(x, str) else x) # Renommer les colonnes df_target.columns = ['Logbook_name', 'Value'] # Appliquer un filtre pour les caractères spéciaux dans la colonne 'Logbook_name' df_target['Logbook_name'] = common_functions.remove_spec_char_from_list(df_target['Logbook_name']) # Supprimer les espaces supplémentaires dans la colonne 'Logbook_name' df_target['Logbook_name'] = df_target['Logbook_name'].str.strip() # Filtrer les lignes qui sont cochées df_target_used = pd.DataFrame() for index, row in df_target.iterrows(): if row['Value'] is not None: df_target_used.loc[len(df_target_used), 'Logbook_name'] = df_target.loc[index, 'Logbook_name'] return df_target_used
[docs] def extract_logbook_date(df_donnees): """ Extraction des cases relatives au mois et à l'année du logbook Args: df_donnees (df): excel p1 Returns: df """ # On extrait les données propres au 'Vessel information' df_month = df_donnees.iloc[17, 5] df_year = df_donnees.iloc[17, 11] month = int(df_month) if isinstance(df_month, (int, float)) and not pd.isna(df_month) else 0 year = int(df_year) if isinstance(df_year, (int, float)) and not pd.isna(df_year) else 0 date = {'Logbook_name': ['Month', 'Year'], 'Value': [int(month), int(year)]} df_date = pd.DataFrame(date) df_date['Logbook_name'] = common_functions.remove_spec_char_from_list(df_date['Logbook_name']) return df_date
[docs] def extract_bait(df_donnees): """ Extraction des cases relatives au type d'appât utilisé Args: df_donnees (df): excel p1 Returns: df """ # On extrait les données df_squid = df_donnees.iloc[19, 16] df_sardine = df_donnees.iloc[19, 20] df_mackerel = df_donnees.iloc[19, 24] df_muroaji = df_donnees.iloc[19, 28] df_other = df_donnees.iloc[19, 32] bait = {'Logbook_name': ['Squid', 'Sardine', 'Mackerel', 'Muroaji', 'Other'], 'Value': [df_squid, df_sardine, df_mackerel, df_muroaji, df_other]} df_bait = pd.DataFrame(bait) # Filtrer les lignes qui sont cochées df_bait_used = pd.DataFrame() for index, row in df_bait.iterrows(): if row['Value'] is not None: df_bait_used.loc[len(df_bait_used), 'Logbook_name'] = df_bait.loc[index, 'Logbook_name'] return df_bait_used
[docs] def extract_positions(df_donnees): """ Extraction des cases relatives aux données de position Args: df_donnees (df): excel p1 Returns: df """ data = df_donnees.iloc[24:55, :7] colnames = ['Day', 'Latitude_Degrees', 'Latitude_Minutes', 'Latitude_Direction', 'Longitude_Degrees', 'Longitude_Minutes', 'Longitude_Direction'] data.columns = colnames # On converti les données de position en degrés décimal data['Latitude'] = common_functions.dms_to_decimal(data['Latitude_Degrees'], data['Latitude_Minutes'], data['Latitude_Direction']) data['Longitude'] = common_functions.dms_to_decimal(data['Longitude_Degrees'], data['Longitude_Minutes'], data['Longitude_Direction']) # Supprimer les lignes avec des valeurs nulles et conserver les colonnes d'intérêt data = data.dropna(subset=['Latitude', 'Longitude']) df_position = data[['Latitude', 'Longitude']] df_position.reset_index(drop=True, inplace=True) return df_position
[docs] def get_vessel_activity_topiaid(startTimeStamp, allData): """ Fonction qui prend en argument une heure de depart et qui donne un topiaID de VesselActivity en fonction du type et du contenu de l'entrée Args: startTimeStamp (date): information horaire - si type date alors Fishing operation, sinon on regarde le texte dans la cellule allData (json): données de références Returns: topiaID de l'activité détectée """ if ":" in str(startTimeStamp): code = "FO" elif re.findall(r"[0-9]{4}", startTimeStamp): code = "FO" elif re.findall("cruis", startTimeStamp.lower()): code = "CRUISE" elif re.findall("crus", startTimeStamp.lower()): code = "CRUISE" elif re.findall("port", startTimeStamp.lower()): code = "PORT" elif startTimeStamp is None: return None else: code = "OTH" vessel_activities = allData["VesselActivity"]["longline"] for vessel_activity in vessel_activities: if vessel_activity.get("code") == code: return vessel_activity["topiaId"], vessel_activity["label1"] return None
[docs] def extract_time(df_donnees, allData): """ Extraction des cases relatives aux horaires des coups de pêche Args: df_donnees (df): excel p1 Returns: df: type horaire, sauf si le bateau est en mouvement """ day = df_donnees.iloc[24:55, 0] df_time = df_donnees.iloc[24:55, 7:8] colnames = ['Time'] df_time.columns = colnames df_time['Time'] = df_time['Time'].apply(common_functions.convert_to_time_or_text) df_time.reset_index(drop=True, inplace=True) vessel_activities = np.empty((len(day), 1), dtype=object) for ligne in range(len(day)): vessel_activity = get_vessel_activity_topiaid( df_time.iloc[ligne]['Time'], allData) vessel_activities[ligne, 0] = vessel_activity[0] np_time = np.column_stack((day, df_time, vessel_activities)) df_time = pd.DataFrame(np_time, columns=['Day', 'Time', 'VesselActivity']) return df_time
[docs] def extract_temperature(df_donnees): """ Extraction des cases relatives aux températures Args: df_donnees (df): excel p1 Returns: df """ df_temp = df_donnees.iloc[24:55, 8:9] colnames = ['Temperature'] df_temp.columns = colnames df_temp.reset_index(drop=True, inplace=True) return df_temp
[docs] def extract_fishing_effort(df_donnees): """ Extraction des cases relatives aux efforts de pêche Args: df_donnees (df): excel p1 Returns: df """ df_fishing_effort = df_donnees.iloc[24:55, [0, 9, 10, 11]].copy() df_fishing_effort.columns = ['Day', 'Hooks per basket', 'Total hooks', 'Total lightsticks'] try: df_fishing_effort['Total hooks / Hooks per basket'] = common_functions.convert_to_int(df_fishing_effort['Total hooks']) / common_functions.convert_to_int(df_fishing_effort['Hooks per basket']) except TypeError: df_fishing_effort['Total hooks / Hooks per basket'] = None df_fishing_effort.reset_index(drop=True, inplace=True) return df_fishing_effort
[docs] def extract_fish_p1(df_donnees): """ Extraction des cases relatives à ce qui a été pêché Args: df_donnees (df): excel p1 Returns: df """ df_fishes = df_donnees.iloc[24:55, 12:36] colnames = ['No RET SBF', 'Kg RET SBF', 'No RET ALB', 'Kg RET ALB', 'No RET BET', 'Kg RET BET', 'No RET YFT', 'Kg RET YFT', 'No RET SWO', 'Kg RET SWO', 'No RET MLS', 'Kg RET MLS', 'No RET BUM', 'Kg RET BUM', 'No RET BLM', 'Kg RET BLM', 'No RET SFA', 'Kg RET SFA', 'No RET SSP', 'Kg RET SSP', 'No RET OIL', 'Kg RET OIL', 'No RET MZZ', 'Kg RET MZZ'] df_fishes.columns = colnames df_fishes = df_fishes.map(common_functions.zero_if_empty) df_fishes.reset_index(drop=True, inplace=True) return df_fishes
[docs] def extract_bycatch_p2(df_donnees): """ Extraction des cases relatives à ce qui a été pêché mais accessoires Args: df_donnees (df): excel p2 Returns: df """ df_bycatch = df_donnees.iloc[15:46, 1:39] colnames = ['No RET FAL', 'Kg RET FAL', 'No ESC FAL', 'No DIS FAL', 'No RET BSH', 'Kg RET BSH', 'No ESC BSH', 'No DIS BSH', 'No RET MAK', 'Kg RET MAK', 'No ESC MAK', 'No DIS MAK', 'No RET MSK', 'Kg RET MSK', 'No ESC MSK', 'No DIS MSK', 'No RET SPN', 'Kg RET SPN', 'No ESC SPN', 'No DIS SPN', 'No RET TIG', 'Kg RET TIG', 'No ESC TIG', 'No DIS TIG', 'No RET PSK', 'Kg RET PSK', 'No ESC PSK', 'No DIS PSK', 'No ESC THR', 'No DIS THR', 'No ESC OCS', 'No DIS OCS', 'No ESC MAM', 'No DIS MAM', 'No ESC SBD', 'No DIS SBD', 'No ESC TTX', 'No DIS TTX'] df_bycatch.columns = colnames df_bycatch = df_bycatch.map(common_functions.zero_if_empty) df_bycatch.reset_index(drop=True, inplace=True) return df_bycatch