{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\n# Chargement de vos données\n# Assurez-vous que vous avez votre DataFrame df_train_series chargé\n\ndef detect_sleep_periods(df, variable, threshold, num_values, start_index=0):\n    data = df[variable].values[start_index:start_index+num_values]\n    variable_min = df[variable].min()\n    variable_max = df[variable].max()\n\n    ma_serie = pd.Series(data)\n    \n    sleep_periods = []\n    high_power_indices = np.where(ma_serie > threshold)[0]\n\n    if high_power_indices.any():\n        start_idx = end_idx = high_power_indices[0]\n        consecutive_drops = 0\n\n        for idx in high_power_indices[1:]:\n            if idx == end_idx + 1:\n                end_idx = idx\n            else:\n                duration_seconds = (end_idx - start_idx + 1) * 5\n                if duration_seconds >= 30 * 60:\n                    duration_minutes = duration_seconds / 60\n                    sleep_periods.append((start_idx, end_idx, duration_minutes, threshold))\n                start_idx = end_idx = idx\n\n            if idx != high_power_indices[-1] and idx != high_power_indices[-1] + 1:\n                consecutive_drops += 1\n                if consecutive_drops >= 4:\n                    start_idx = idx - consecutive_drops\n\n        duration_seconds = (end_idx - start_idx + 1) * 5\n        if duration_seconds >= 30 * 60:\n            duration_minutes = duration_seconds / 60\n            sleep_periods.append((start_idx, end_idx, duration_minutes, threshold))\n\n    etapes_en_heures = df.index[start_index:start_index+num_values] * 5 / 3600\n\n    plt.figure(figsize=(12, 6))\n    plt.plot(etapes_en_heures, df[variable][start_index:start_index+num_values], label='enmo')\n    plt.xlabel('Heures')\n    plt.ylabel('Valeur de enmo')\n    plt.ylim(variable_min, variable_max)\n\n    for start, end, _, threshold in sleep_periods:\n        plt.axvline(x=start_index + start * 5 / 3600, color='green', linestyle='--', label=f'Endormissement (Threshold: {threshold})')\n        plt.axvline(x=start_index + end * 5 / 3600, color='red', linestyle='--', label=f'Réveil (Threshold: {threshold})')\n\n    plt.legend(loc=\"upper right\")\n    plt.grid(True)\n\n    print(\"Moments d'endormissement et de réveil :\")\n    for start, end, duration, threshold in sleep_periods:\n        start_hours = start_index + start * 5 / 3600\n        end_hours = start_index + end * 5 / 3600\n        print(f\"Start: {start_hours} heures, End: {end_hours} heures, Durée: {duration} minutes, Threshold: {threshold}\")\n\n    plt.show()\n    return sleep_periods\n\nvariable_name = 'anglez'\nthreshold = 0.05\nnum_values_to_take = 10000\nstart_index = 3000\n\nsleep_periods = detect_sleep_periods(df_train_series, variable_name, threshold, num_values_to_take, start_index)\nENMO signifie \"Euclidean Norm Minus One\". Il s'agit d'une métrique calculée à partir des composants de l'accéléromètre, qui est souvent utilisée dans l'analyse du sommeil et d'autres études comportementales. Le terme \"norme euclidienne\" se réfère à la distance euclidienne dans un espace à plusieurs dimensions. Dans le cas d'un accéléromètre triaxial, ces dimensions seraient les accélérations mesurées sur les axes x, y et z.\n\nAprès ce calcul, toutes les valeurs négatives d'ENMO sont généralement arrondies à zéro.\n\nL'idée derrière le \"moins un\" dans \"Euclidean Norm Minus One\" est de soustraire la gravité (qui a une accélération de 1g, ou environ \n9.81\n \nm/s\n2\n9.81m/s \n2\n ) du calcul. L'objectif est d'isoler l'accélération dynamique due au mouvement de l'accélération totale mesurée.\n\nENMO est utile pour évaluer l'intensité du mouvement. Par exemple, lorsqu'une personne est au repos ou endormie, vous pouvez vous attendre à ce que l'ENMO soit faible. En revanche, lorsqu'une personne est active ou en mouvement, l'ENMO serait élevé. Par conséquent, cette métrique est souvent utilisée dans des algorithmes destinés à identifier des périodes de sommeil ou d'activité.\n\n\n\n\n\n\n\n","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:06:27.490709Z","iopub.execute_input":"2023-11-06T19:06:27.491328Z","iopub.status.idle":"2023-11-06T19:06:29.32415Z","shell.execute_reply.started":"2023-11-06T19:06:27.491285Z","shell.execute_reply":"2023-11-06T19:06:29.323282Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# train_series.parquet","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom ipywidgets import interact, widgets\nimport pandas as pd\nfrom scipy.signal import spectrogram\n\ndef plot_variable_interactive(df, variable, start_index, num_values):\n    if variable not in df.columns:\n        print(\"Variable not found in the DataFrame.\")\n        return\n\n    data = df[variable].values[start_index:start_index + num_values]\n\n    fig, (ax1, ax2, ax3, ax4) = plt.subplots(4, 1, figsize=(12, 16))\n\n    # Graphique 1 : Signal original\n    ax1.plot(data, label=variable)\n    ax1.set_xlabel('Temps')\n    ax1.set_ylabel('Amplitude')\n    ax1.legend()\n    ax1.set_title(f'Amplitude de {variable}')\n    ax1.grid(True)\n\n    # Graphique 2 : Transformation de Fourier\n    fft_result = np.fft.fft(data)\n    sample_rate = 1\n    freqs = np.fft.fftfreq(len(data), 1/sample_rate)\n    positive_freq_indices = np.where(freqs > 0)\n    magnitude_spectrum = np.abs(fft_result[positive_freq_indices])\n    frequencies = freqs[positive_freq_indices]\n    ax2.plot(frequencies, magnitude_spectrum, label='Transformée de Fourier')\n    ax2.set_xlabel('Fréquence (Hz)')\n    ax2.set_ylabel('Amplitude')\n    ax2.set_title(f'Transformée de Fourier de {variable}')\n    ax2.grid(True)\n    ax2.legend()\n\n    # Graphique 3 : Spectre de fréquence\n    fs = 1.0\n    window = 'hann'\n    nperseg = 256\n    noverlap = 128\n    frequencies, times, Sxx = spectrogram(data, fs=fs, window=window, nperseg=nperseg, noverlap=noverlap)\n    ax3.pcolormesh(times, frequencies, 10 * np.log10(Sxx), shading='auto', cmap='viridis')\n    ax3.set_xlabel('Temps (s)')\n    ax3.set_ylabel('Fréquence (Hz)')\n    ax3.set_title(f'Spectrogramme de {variable}')\n    ax3.grid(True)\n\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:06:29.326213Z","iopub.execute_input":"2023-11-06T19:06:29.32706Z","iopub.status.idle":"2023-11-06T19:06:29.398935Z","shell.execute_reply.started":"2023-11-06T19:06:29.32702Z","shell.execute_reply":"2023-11-06T19:06:29.398143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\nfrom tqdm import tqdm\nimport pytz\n\ndef process_and_save_dataframe(df, output_file):\n    # Check if the output file exists\n    if not os.path.exists(output_file):\n        # Create a list of unique series_id\n        unique_series_ids = df['series_id'].unique()\n\n        # Initialize a list to store the final DataFrames\n        final_dfs = []\n\n        # Initialize a global counter for the total progress bar\n        total_progress = tqdm(total=len(unique_series_ids), desc=\"Total Progress\")\n\n        # Define a function to find the nearest timestamp in a given DataFrame\n        def find_nearest_timestamp(df, timestamp):\n            df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True)\n            time_diffs = df['timestamp'].apply(lambda x: (x - timestamp).total_seconds())\n            idx = time_diffs.abs().idxmin()\n            return idx\n\n        # Iterate through series_id one by one\n        for series_id in unique_series_ids:\n            # Create a subset for the given series_id in df\n            subset_series = df[df['series_id'] == series_id].copy()\n\n            # Check if subset_series is not empty\n            if not subset_series.empty:\n                # Convert timestamps to datetime objects in UTC timezone\n                subset_series['timestamp'] = pd.to_datetime(subset_series['timestamp'], utc=True)\n\n                # Initialize a list to store the indexes\n                indexes = []\n\n                # Iterate through rows in the subset of df\n                for _, row in subset_series.iterrows():\n                    timestamp = row['timestamp']\n                    idx = find_nearest_timestamp(subset_series, timestamp)\n                    indexes.append(idx)\n\n                # Add the 'index_train_series' column to the subset of df\n                subset_series['index_train_series'] = indexes\n\n                # Add the columns 'event', 'x_timestamp', and 'y_timestamp' to the subset of df\n                # only if they exist in the original df\n                if 'x_timestamp' in df.columns and 'y_timestamp' in df.columns:\n                    subset_series['x_timestamp'] = df.iloc[0]['x_timestamp']\n                    subset_series['y_timestamp'] = df.iloc[0]['y_timestamp']\n\n                # Add the subset of df with the new columns to the final result\n                final_dfs.append(subset_series)\n\n            else:\n                print(f\"No rows found for series_id {series_id}\")\n\n            # Update the total progress bar\n            total_progress.update(1)\n\n        # Close the total progress bar\n        total_progress.close()\n\n        # Concatenate all the final DataFrames into a single DataFrame\n        result_df = pd.concat(final_dfs)\n\n        # Reset the index of the resulting DataFrame\n        result_df.reset_index(drop=True, inplace=True)\n\n        # Display the resulting DataFrame\n        print(result_df)\n\n        # Save the result_df DataFrame to a CSV file\n        result_df.to_csv(output_file, index=False)\n    else:\n        # If the file exists, load it as a DataFrame\n        result_df = pd.read_csv(output_file)\n    print (df_train_series)\n    # Now you can use result_df as needed\n    return result_df\n\n\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:06:29.400438Z","iopub.execute_input":"2023-11-06T19:06:29.40109Z","iopub.status.idle":"2023-11-06T19:06:29.418659Z","shell.execute_reply.started":"2023-11-06T19:06:29.40105Z","shell.execute_reply":"2023-11-06T19:06:29.417568Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def describ(print_output=True):\n    # Examinez les premières lignes de chaque ensemble de données\n    dataframes = [df_train_series,  df_train_events]\n    data_names = [\"Données d'entraînement (train_series)\",  \"Événements d'entraînement (train_events)\"]\n\n    for df, name in zip(dataframes, data_names):\n        if print_output:\n            print(f\"Têtes des {name} :\")\n            print(df.head())\n\n            print(f\"\\nInfos de base sur les {name} :\")\n            print(df.info())\n\n            print(f\"\\nContrôle des valeurs nulles dans les {name} :\")\n            print(df.isnull().sum())\n\n            if name != \"Événements d'entraînement (train_events)\":\n                print(f\"\\nStatistiques descriptives des {name} :\")\n                print(df.describe())\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:06:29.421298Z","iopub.execute_input":"2023-11-06T19:06:29.421608Z","iopub.status.idle":"2023-11-06T19:06:29.430064Z","shell.execute_reply.started":"2023-11-06T19:06:29.421582Z","shell.execute_reply":"2023-11-06T19:06:29.428887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\n\ndef generate_visualizations(dataframe, column_name, title, x_label=None, y_max=None):\n    \n    data = dataframe[column_name]\n    \n    plt.figure(figsize=(10, 6))\n    \n    # Générer des bacs équidistants\n    bins = np.linspace(data.min(), data.max(), 50)\n    \n    # Créez un histogramme en utilisant les bacs \n    plt.hist(data, bins=bins, color='blue', alpha=0.7, edgecolor='black')\n    \n    plt.title(title)\n    plt.xlabel(x_label if x_label is not None else column_name)\n    plt.ylabel('Frequency')\n\n    # Si y_max est fourni, utilisez-le pour définir la limite supérieure de l'axe y.\n    # Sinon, définissez la limite supérieure de l'axe y pour qu'elle soit 10% plus grande que la valeur maximale des données.\n    if y_max:\n        plt.ylim(0, y_max)\n    else:\n        plt.ylim(0, data.max() * 1.1)\n    \n    plt.grid(axis='y', linestyle='--', alpha=0.7)\n    plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:06:29.431812Z","iopub.execute_input":"2023-11-06T19:06:29.432594Z","iopub.status.idle":"2023-11-06T19:06:29.442784Z","shell.execute_reply.started":"2023-11-06T19:06:29.432553Z","shell.execute_reply":"2023-11-06T19:06:29.441739Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Charger le dataframe depuis un fichier Parquet\n# Charger les données","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:06:29.444158Z","iopub.execute_input":"2023-11-06T19:06:29.444449Z","iopub.status.idle":"2023-11-06T19:06:29.458273Z","shell.execute_reply.started":"2023-11-06T19:06:29.444425Z","shell.execute_reply":"2023-11-06T19:06:29.457365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_series = pd.read_parquet(\"/kaggle/input/child-mind-institute-detect-sleep-states/train_series.parquet\")","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:06:29.459451Z","iopub.execute_input":"2023-11-06T19:06:29.460351Z","iopub.status.idle":"2023-11-06T19:07:22.866706Z","shell.execute_reply.started":"2023-11-06T19:06:29.460313Z","shell.execute_reply":"2023-11-06T19:07:22.865644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#df_test_series = pd.read_parquet(\"/kaggle/input/child-mind-institute-detect-sleep-states/test_series.parquet\")\ndf_train_events = pd.read_csv(\"/kaggle/input/child-mind-institute-detect-sleep-states/train_events.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:07:22.871594Z","iopub.execute_input":"2023-11-06T19:07:22.871952Z","iopub.status.idle":"2023-11-06T19:07:22.943471Z","shell.execute_reply.started":"2023-11-06T19:07:22.871923Z","shell.execute_reply":"2023-11-06T19:07:22.942398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_series.info()","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:07:22.945303Z","iopub.execute_input":"2023-11-06T19:07:22.945709Z","iopub.status.idle":"2023-11-06T19:07:22.964449Z","shell.execute_reply.started":"2023-11-06T19:07:22.945669Z","shell.execute_reply":"2023-11-06T19:07:22.963026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"describ()","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:07:22.970534Z","iopub.execute_input":"2023-11-06T19:07:22.971625Z","iopub.status.idle":"2023-11-06T19:07:45.98833Z","shell.execute_reply.started":"2023-11-06T19:07:22.971579Z","shell.execute_reply":"2023-11-06T19:07:45.987164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"[](http://)","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n\n# Sélectionnez les lignes où 'step' est nul et extrayez la colonne 'series_id'\nseries_with_null_step = df_train_events.loc[df_train_events['step'].isnull(), 'series_id']\n\n# Sélectionnez les lignes où à la fois 'step' et 'timestamp' sont nuls et extrayez la colonne 'series_id'\nseries_with_both_null = df_train_events.loc[(df_train_events['step'].isnull()) & (df_train_events['timestamp'].isnull()), 'series_id']\n\n# Sélectionnez les lignes où 'timestamp' est nul et extrayez la colonne 'series_id'\nseries_with_null_timestamp = df_train_events.loc[df_train_events['timestamp'].isnull(), 'series_id']\n\n\n\n# Affichez les séries résultantes\nprint(\"Series with null step:\")\nprint(series_with_null_step)\n\nprint(\"\\nSeries with both null step and timestamp:\")\nprint(series_with_both_null)\n\nprint(\"\\nSeries with null timestamp:\")\nprint(series_with_null_timestamp)\n\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:07:45.989676Z","iopub.execute_input":"2023-11-06T19:07:45.989977Z","iopub.status.idle":"2023-11-06T19:07:46.004477Z","shell.execute_reply.started":"2023-11-06T19:07:45.989951Z","shell.execute_reply":"2023-11-06T19:07:46.003321Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Supression des valeurs null","metadata":{}},{"cell_type":"code","source":"# Supprimez les lignes où 'step' et 'timestamp' sont nuls\ndf_train_events.dropna(subset=['step', 'timestamp'], inplace=True)","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:07:46.005972Z","iopub.execute_input":"2023-11-06T19:07:46.006392Z","iopub.status.idle":"2023-11-06T19:07:46.020617Z","shell.execute_reply.started":"2023-11-06T19:07:46.006353Z","shell.execute_reply":"2023-11-06T19:07:46.019464Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"describ()","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:07:46.021781Z","iopub.execute_input":"2023-11-06T19:07:46.022422Z","iopub.status.idle":"2023-11-06T19:08:08.929933Z","shell.execute_reply.started":"2023-11-06T19:07:46.022388Z","shell.execute_reply":"2023-11-06T19:08:08.928783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! pip install filterpy\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:08:08.931464Z","iopub.execute_input":"2023-11-06T19:08:08.932353Z","iopub.status.idle":"2023-11-06T19:08:23.946617Z","shell.execute_reply.started":"2023-11-06T19:08:08.932313Z","shell.execute_reply":"2023-11-06T19:08:23.945694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generate_visualizations(df_train_series, 'anglez', 'Distribution de l’anglez',y_max=10000000)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:08:23.947846Z","iopub.execute_input":"2023-11-06T19:08:23.948173Z","iopub.status.idle":"2023-11-06T19:08:33.501978Z","shell.execute_reply.started":"2023-11-06T19:08:23.948144Z","shell.execute_reply":"2023-11-06T19:08:33.501163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generate_visualizations(df_train_series, 'enmo', 'Distribution de l’enmo', y_max=30000)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:08:33.502975Z","iopub.execute_input":"2023-11-06T19:08:33.503827Z","iopub.status.idle":"2023-11-06T19:08:41.256366Z","shell.execute_reply.started":"2023-11-06T19:08:33.503795Z","shell.execute_reply":"2023-11-06T19:08:41.255167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm.notebook import tqdm\n\ndef plot_df_series_with_limit(df, n):\n    num_subplots = min(3, len(df['series_id'].unique()))  # Le nombre de sous-graphiques est au maximum 3 ou le nombre de séries si inférieur à 3\n    if num_subplots == 0:\n        print(\"Aucune série à afficher.\")\n        return\n    \n    fig, axes = plt.subplots(num_subplots, 1, figsize=(10, 8), sharex=True)\n    \n    for i, ax in tqdm(enumerate(axes), total=num_subplots, desc=\"Création des graphiques\"):\n        series_id = df['series_id'].unique()[i]\n        ax.set_title('series_id: ' + series_id, loc='left', fontsize=10)\n        x = df[df['series_id'] == series_id]['step'][:n]\n        y_enmo = df[df['series_id'] == series_id]['enmo'][:n]\n        y_anglez = df[df['series_id'] == series_id]['anglez'][:n]\n        ax.plot(x, y_enmo, label='enmo', color='magenta', lw=1, alpha=0.9)\n        ax.set_ylabel('enmo', fontsize=9)\n        ax.tick_params(labelsize=9)\n        \n        ax2 = ax.twinx()\n        ax2.plot(x, y_anglez, label='anglez', color='lime', lw=1, alpha=0.9)\n        ax2.set_ylabel('anglez', fontsize=9)\n    \n    plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:08:41.257521Z","iopub.execute_input":"2023-11-06T19:08:41.257831Z","iopub.status.idle":"2023-11-06T19:08:41.272641Z","shell.execute_reply.started":"2023-11-06T19:08:41.257792Z","shell.execute_reply":"2023-11-06T19:08:41.271379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_df_series_with_limit(df_train_series, 20000)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:08:41.274104Z","iopub.execute_input":"2023-11-06T19:08:41.274461Z","iopub.status.idle":"2023-11-06T19:10:51.449102Z","shell.execute_reply.started":"2023-11-06T19:08:41.274431Z","shell.execute_reply":"2023-11-06T19:10:51.447807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nfrom scipy.signal import butter, filtfilt\nimport matplotlib.pyplot as plt\n\ndef apply_lowpass_filter(data, column, start_row, num_rows, cutoff_freq, sampling_freq, order=5):\n    # Créez un sous-DataFrame à partir des lignes spécifiées\n    sub_df = data.iloc[start_row:start_row + num_rows]\n\n    # Extrait la série à partir de la colonne spécifiée\n    enmo_series = sub_df[column]\n\n    # Fonction pour appliquer un filtre passe-bas\n    def butter_lowpass(cutoff, fs, order=5):\n        nyquist = 0.5 * fs\n        normal_cutoff = cutoff / nyquist\n        b, a = butter(order, normal_cutoff, btype='low', analog=False)\n        return b, a\n\n    def butter_lowpass_filter(data, cutoff, fs, order=5):\n        b, a = butter_lowpass(cutoff, fs, order=order)\n        y = filtfilt(b, a, data)\n        return y\n\n    # Appliquer le filtre passe-bas à la série\n    filtered_series = butter_lowpass_filter(enmo_series, cutoff_freq, sampling_freq, order=order)\n\n    # Ajouter les données filtrées à un nouveau DataFrame\n    filtered_df = sub_df.copy()\n    filtered_df[column] = filtered_series\n\n    # Visualiser les données originales et filtrées\n    plt.figure(figsize=(10, 6))\n    plt.plot(sub_df.index, enmo_series, label=f'Données {column} originales', color='b')\n    plt.plot(sub_df.index, filtered_series, label=f'Données {column} filtrées', color='r')\n    plt.xlabel('Temps')\n    plt.ylabel(column)\n    plt.legend()\n    plt.show()\n\n    return filtered_df\n\n# Exemple d'utilisation de la fonction\ndata = df_train_series\ncutoff_freq = 0.1\nsampling_freq = 1.0\nstart_row = 0\nnum_rows = 1000\nfiltered_data = apply_lowpass_filter(data, 'enmo', start_row, num_rows, cutoff_freq, sampling_freq)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:10:51.450874Z","iopub.execute_input":"2023-11-06T19:10:51.452036Z","iopub.status.idle":"2023-11-06T19:10:51.737017Z","shell.execute_reply.started":"2023-11-06T19:10:51.451984Z","shell.execute_reply":"2023-11-06T19:10:51.735958Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nfrom scipy.signal import butter, filtfilt, savgol_filter\nfrom pykalman import KalmanFilter\nfrom scipy.signal import wiener\nimport matplotlib.pyplot as plt\n\ndef apply_filters(data, column, start_idx, num_values):\n    data = data.iloc[start_idx:start_idx+num_values]\n\n    def butter_lowpass(cutoff, fs):\n        nyquist = 0.5 * fs\n        normal_cutoff = cutoff / nyquist\n        b, a = butter(5, normal_cutoff, btype='low', analog=False)\n        return b, a\n\n    def butter_highpass(cutoff, fs):\n        nyquist = 0.5 * fs\n        normal_cutoff = cutoff / nyquist\n        b, a = butter(5, normal_cutoff, btype='high', analog=False)\n        return b, a\n\n    def butter_bandpass(lowcut, highcut, fs):\n        nyquist = 0.5 * fs\n        low = lowcut / nyquist\n        high = highcut / nyquist\n        b, a = butter(5, [low, high], btype='band', analog=False)\n        return b, a\n\n    def butter_lowpass_filter(data, cutoff, fs):\n        b, a = butter_lowpass(cutoff, fs)\n        if len(data) < 2 * len(b):\n            return data\n        y = filtfilt(b, a, data, padlen=len(data) - 1)\n        return y\n\n    def butter_highpass_filter(data, cutoff, fs):\n        b, a = butter_highpass(cutoff, fs)\n        if len(data) < 2 * len(b):\n            return data\n        y = filtfilt(b, a, data, padlen=len(data) - 1)\n        return y\n\n    def butter_bandpass_filter(data, lowcut, highcut, fs):\n        b, a = butter_bandpass(lowcut, highcut, fs)\n        if len(data) < 2 * len(b):\n            return data\n        y = filtfilt(b, a, data, padlen=len(data) - 1)\n        return y\n\n    def kalman_filter(data):\n        kf = KalmanFilter(initial_state_mean=0, n_dim_obs=1)\n        filtered_state_means, _ = kf.filter(data)\n        return filtered_state_means\n\n    def savitzky_golay_filter(data):\n        window_length = 5\n        polyorder = 2\n        if len(data) < window_length:\n            return data\n        filtered = savgol_filter(data, window_length, polyorder)\n        return filtered\n\n    def wiener_filter(data):\n        if len(data) < 2:\n            return data\n        filtered = wiener(data)\n        return filtered\n\n    filtered_lowpass = butter_lowpass_filter(data[column], 0.1, 1.0)\n    filtered_highpass = butter_highpass_filter(data[column], 0.1, 1.0)\n    filtered_bandpass = butter_bandpass_filter(data[column], 0.01, 0.1, 1.0)\n    filtered_kalman = kalman_filter(data[column])\n    filtered_savgol = savitzky_golay_filter(data[column])\n    filtered_wiener = wiener_filter(data[column])\n\n    return filtered_lowpass, filtered_highpass, filtered_bandpass, filtered_kalman, filtered_savgol, filtered_wiener\n\n# Spécifier le début et le nombre de valeurs traitées\nstart_idx = 0  # Remplacez par l'indice de départ souhaité\nnum_values = 70  # Assurez-vous que num_values est égal à la longueur de filtered_lowpass\ndf=df_train_series.copy()\n# Appliquer les filtres avec les paramètres spécifiés\nfiltered_lowpass, filtered_highpass, filtered_bandpass, filtered_kalman, filtered_savgol, filtered_wiener = apply_filters(df, 'enmo', start_idx, num_values)\n\n# Créer un graphique séparé pour chaque filtre\nfilters = [filtered_lowpass, filtered_highpass, filtered_bandpass, filtered_kalman, filtered_savgol, filtered_wiener]\nfilter_labels = ['Filtre passe-bas', 'Filtre passe-haut', 'Filtre passe-bande', 'Filtre de Kalman', 'Filtre de Savitzky-Golay', 'Filtre de Wiener']\n\nfor i in range(len(filters)):\n    plt.figure(figsize=(12, 8))\n    plt.plot(df.index[start_idx:start_idx+num_values], df['enmo'].iloc[start_idx:start_idx+num_values], label='Données ENMO originales', color='b')\n    plt.plot(df.index[start_idx:start_idx+num_values], filters[i], label=filter_labels[i])\n    plt.xlabel('Temps')\n    plt.ylabel('ENMO')\n    plt.legend()\n    plt.show()\n\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:31:05.217422Z","iopub.execute_input":"2023-11-06T19:31:05.217899Z","iopub.status.idle":"2023-11-06T19:31:19.274215Z","shell.execute_reply.started":"2023-11-06T19:31:05.217862Z","shell.execute_reply":"2023-11-06T19:31:19.273064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:10:59.647443Z","iopub.execute_input":"2023-11-06T19:10:59.647769Z","iopub.status.idle":"2023-11-06T19:11:00.155081Z","shell.execute_reply.started":"2023-11-06T19:10:59.647743Z","shell.execute_reply":"2023-11-06T19:11:00.152575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\n\n# Définissez la taille du groupe\ngroup_size = 720\n\n# Créez une colonne pour l'indice de groupe\ndf_train_series['group_index'] = np.arange(len(df_train_series)) // group_size\n\n# Calculez la médiane de 'enmo' et 'anglez' pour chaque groupe\ngrouped = df_train_series.groupby(['series_id', 'group_index'])\nmedians = grouped[['enmo', 'anglez']].median()\n\n# Réinitialisez l'indice pour obtenir les colonnes 'series_id' et 'group_index'\nmedians = medians.reset_index()\n\n# Supprimez la colonne 'group_index' car elle n'est plus nécessaire\nmedians = medians.drop(columns=['group_index'])\n\n# Affichez le nouveau DataFrame\nprint(medians)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.156105Z","iopub.status.idle":"2023-11-06T19:11:00.156517Z","shell.execute_reply.started":"2023-11-06T19:11:00.156327Z","shell.execute_reply":"2023-11-06T19:11:00.156346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import plotly.graph_objs as go\nimport ipywidgets as widgets\nfrom ipywidgets import interact\nimport numpy as np\n\n# Définissez la fonction qui crée deux graphiques interactifs séparés\ndef plot_variable_interactive1(df, variable, start_index, num_values):\n    # Sélectionnez les données en fonction des paramètres fournis\n    data_subset = df[start_index:start_index+num_values]\n    \n    # Créez une figure Plotly pour la série temporelle d'origine\n    fig1 = go.Figure()\n    fig1.add_trace(go.Scatter(x=data_subset.index, y=data_subset[variable], mode='lines', name=variable))\n    fig1.update_layout(title=f'Série Temporelle de {variable}', xaxis_title='Index', yaxis_title=variable)\n    \n    # Calculez la transformation de Fourier\n    fourier_transform = np.fft.fft(data_subset[variable])\n    frequencies = np.fft.fftfreq(len(fourier_transform))\n    \n    # Créez une figure Plotly pour la transformation de Fourier\n    fig2 = go.Figure()\n    fig2.add_trace(go.Scatter(x=frequencies, y=np.abs(fourier_transform), mode='lines', name='Transformée de Fourier'))\n    \n    # Affichez les deux graphiques interactifs séparés\n    fig1.show()\n    fig2.show()\n\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.15835Z","iopub.status.idle":"2023-11-06T19:11:00.159071Z","shell.execute_reply.started":"2023-11-06T19:11:00.158849Z","shell.execute_reply":"2023-11-06T19:11:00.15887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Appel de la fonction en passant votre DataFrame et le nom de la variable\n\ndf=df_train_series.copy()\ninteract(plot_variable_interactive, df=widgets.fixed(df), variable='enmo', start_index=(0, 100000, 10), num_values=(100, 100000, 10))\ninteract(plot_variable_interactive, df=widgets.fixed(df), variable='anglez', start_index=(0, 100000, 10), num_values=(100, 100000, 10))\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.160423Z","iopub.status.idle":"2023-11-06T19:11:00.161222Z","shell.execute_reply.started":"2023-11-06T19:11:00.161002Z","shell.execute_reply":"2023-11-06T19:11:00.161029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Appel de la fonction en passant votre DataFrame et le nom de la variable\n\ndf=df_train_series.copy()\ninteract(plot_variable_interactive1, df=widgets.fixed(df), variable='enmo', start_index=(0, 100000, 10), num_values=(100, 100000, 10))\ninteract(plot_variable_interactive1, df=widgets.fixed(df), variable='anglez', start_index=(0, 100000, 10), num_values=(100, 100000, 10))\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.162707Z","iopub.status.idle":"2023-11-06T19:11:00.163115Z","shell.execute_reply.started":"2023-11-06T19:11:00.162903Z","shell.execute_reply":"2023-11-06T19:11:00.16292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Utilisation de la fonction avec votre DataFrame et le chemin de sauvegarde\ndf_train_series = pd.read_parquet(\"/kaggle/input/child-mind-institute-detect-sleep-states/train_series.parquet\")\ndf_train_events = pd.read_csv('/kaggle/input/child-mind-institute-detect-sleep-states/train_events.csv')\nresult_df = process_and_save_dataframe(df_train_series, '/kaggle/working/resultat.csv')","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.164527Z","iopub.status.idle":"2023-11-06T19:11:00.164907Z","shell.execute_reply.started":"2023-11-06T19:11:00.164728Z","shell.execute_reply":"2023-11-06T19:11:00.164746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"    result_df.to_csv('/kaggle/working/resultat.csv', index=False)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.166582Z","iopub.status.idle":"2023-11-06T19:11:00.166935Z","shell.execute_reply.started":"2023-11-06T19:11:00.166757Z","shell.execute_reply":"2023-11-06T19:11:00.166773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result_df","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.168516Z","iopub.status.idle":"2023-11-06T19:11:00.168884Z","shell.execute_reply.started":"2023-11-06T19:11:00.168709Z","shell.execute_reply":"2023-11-06T19:11:00.168727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inds = result_df[\"index_train_series\"]\n\n# Convertir la Series en une liste\ninds_list = inds.tolist()","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.170128Z","iopub.status.idle":"2023-11-06T19:11:00.170854Z","shell.execute_reply.started":"2023-11-06T19:11:00.170657Z","shell.execute_reply":"2023-11-06T19:11:00.170679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# nous avons ainsi la liste des index de tous les point ","metadata":{}},{"cell_type":"code","source":"df_result = result_df.copy()","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.172243Z","iopub.status.idle":"2023-11-06T19:11:00.17262Z","shell.execute_reply.started":"2023-11-06T19:11:00.172442Z","shell.execute_reply":"2023-11-06T19:11:00.17246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Nous passons par un tableau numpy pour éviter l'erreur /tmp/ipykernel_32/3203288784.py:43: PerformanceWarning: DataFrame is highly fragmented.  This is usually the result of calling `frame.insert` many times, which has poor performance.  Consider joining all columns at once using pd.concat(axis=1) instead. To get a de-fragmented frame, use `newframe = frame.copy()`\n  df_final[f'colonne{j + 3}'] = value","metadata":{}},{"cell_type":"markdown","source":"En valeurs absolues","metadata":{}},{"cell_type":"markdown","source":"----------------------------\n","metadata":{}},{"cell_type":"code","source":"df_train_series.copy()","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.17396Z","iopub.status.idle":"2023-11-06T19:11:00.174404Z","shell.execute_reply.started":"2023-11-06T19:11:00.174215Z","shell.execute_reply":"2023-11-06T19:11:00.174233Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Créez un widget interactif pour sélectionner le début de l'index et le nombre de valeurs\ndf = pd.DataFrame({'data': np.random.randn(10000)})\ninteract(plot_variable_interactive, df=widgets.fixed(df), variable='data', start_index=(0, 9900, 100), num_values=(100, 1000, 100))copy\n.copinteract(plot_variable_interactive, df=widgets.fixed(df), variable='data', start_index=(0, 9900, 100), num_values=(100, 1000, 100))","metadata":{"execution":{"iopub.status.busy":"2023-11-06T08:28:24.968961Z","iopub.execute_input":"2023-11-06T08:28:24.969317Z","iopub.status.idle":"2023-11-06T08:28:24.980528Z","shell.execute_reply.started":"2023-11-06T08:28:24.969288Z","shell.execute_reply":"2023-11-06T08:28:24.976954Z"}}},{"cell_type":"code","source":"! pi install filterpy","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.175926Z","iopub.status.idle":"2023-11-06T19:11:00.176345Z","shell.execute_reply.started":"2023-11-06T19:11:00.176159Z","shell.execute_reply":"2023-11-06T19:11:00.176178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Voici les étapes pour calculer X et Y :\n\nSupposons que l'axe Z mesure l'accélération gravitationnelle (en général, il devrait être proche de 9.81 m/s² sur Terre). Vous pouvez considérer cette valeur comme \"g\" (l'accélération due à la gravité).\n\nMesurez l'accélération totale de l'appareil, que nous appellerons \"a.\" Cela inclut l'accélération due à la gravité.\n\nCalculez l'angle d'inclinaison θ par rapport à la verticale à l'aide de l'axe Z :\n\nθ = arccos(a / g)\n\nUne fois que vous avez θ, vous pouvez calculer les composantes X et Y de l'accélération totale a :\n\nX = a * sin(θ)\nY = a * cos(θ)\n\n\nL'angle d'inclinaison θ est calculé de façon trigonométrique à partir du ratio entre l'accélération mesurée a et l'accélération gravitationnelle g. Cette formule d'arc cosinus est une relation géométrique exacte.\n\nLes composantes X et Y sont ensuite calculées en utilisant les fonctions trigonométriques sinus et cosinus sur cet angle θ. Les formules utilisées (X = a * sin(θ) et Y = a * cos(θ)) découlent directement des définitions mathématiques du sinus et du cosinus.\n\nDonc si l'accélération a et l'accélération gravitationnelle g sont mesurées précisément, et en l'absence d'autres forces, les valeurs X et Y calculées représenteront de façon fiable les composantes selon ces axes de l'accélération totale.","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\n\n# Supposons que vous avez un DataFrame df_train_series avec les colonnes series_id, step, timestamp, anglez et enmo.\n\n# Ajoutez les colonnes anglex et angley en utilisant les valeurs de enmo et anglez.\ng = 9.81  # Accélération gravitationnelle en m/s²\ndf_train_series['theta'] = np.arccos(np.clip(df_train_series['enmo'] / g, -1, 1))  # Calcule l'angle θ en radian en évitant les valeurs invalides\ndf_train_series['anglex'] = df_train_series['enmo'] * np.sin(df_train_series['theta'])  # Calcule l'angle x en m/s²\ndf_train_series['angley'] = df_train_series['enmo'] * np.cos(df_train_series['theta'])  # Calcule l'angle y en m/s²\n\n# Affichez le DataFrame mis à jour.\nprint(df_train_series)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.177601Z","iopub.status.idle":"2023-11-06T19:11:00.178423Z","shell.execute_reply.started":"2023-11-06T19:11:00.178222Z","shell.execute_reply":"2023-11-06T19:11:00.178243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# Utilisez la fonction en passant la variable souhaitée\ngenerate_interactive_plot(df_train_series,'anglez',75)  \n\ngenerate_interactive_plot(df_train_series,'enmo',2)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.180085Z","iopub.status.idle":"2023-11-06T19:11:00.180423Z","shell.execute_reply.started":"2023-11-06T19:11:00.180258Z","shell.execute_reply":"2023-11-06T19:11:00.180274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\ndfs=df_train_series.copy()\n# Supposons que 'anglez' et 'enmo' sont les noms des colonnes dans df_train_series\ndfs['anglez'] = df_train_series['anglez'].abs()  # Mettre en valeur absolue\n\n# Créer la nouvelle colonne 'tot'\ndfs['tot'] = (dfs['anglez'] /80) + dfs['enmo']\n\n# Sauvegarder le DataFrame au format Parquet\ndfs.to_parquet('df.parquet')","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.18162Z","iopub.status.idle":"2023-11-06T19:11:00.182017Z","shell.execute_reply.started":"2023-11-06T19:11:00.181818Z","shell.execute_reply":"2023-11-06T19:11:00.181835Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"generate_interactive_plot(dfs,'tot',14)  ","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.183856Z","iopub.status.idle":"2023-11-06T19:11:00.18423Z","shell.execute_reply.started":"2023-11-06T19:11:00.184052Z","shell.execute_reply":"2023-11-06T19:11:00.184069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generate_interactive_plot(dfs,'anglez',14)  ","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.185573Z","iopub.status.idle":"2023-11-06T19:11:00.185941Z","shell.execute_reply.started":"2023-11-06T19:11:00.185763Z","shell.execute_reply":"2023-11-06T19:11:00.185782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_series.describe()","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.186726Z","iopub.status.idle":"2023-11-06T19:11:00.187117Z","shell.execute_reply.started":"2023-11-06T19:11:00.186904Z","shell.execute_reply":"2023-11-06T19:11:00.186921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"variable_name = 'enmo'\nlevel_of_change = 0.002  # Remplacez par la valeur réelle de changement d'état\nnum_values_to_take = 15000\nstart_index = 3000\nmanual_max_y = 2  # Remplacez par la valeur maximale que vous souhaitez\n\nsleep_periods = detect_sleep_periods(df_train_series, variable_name, level_of_change, num_values_to_take, start_index, manual_max_y)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.189304Z","iopub.status.idle":"2023-11-06T19:11:00.189646Z","shell.execute_reply.started":"2023-11-06T19:11:00.189481Z","shell.execute_reply":"2023-11-06T19:11:00.189497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Fonction pour détecter les périodes de sommeil\ndef detect_sleep_periods(df, variable, level_of_change, num_values, start_index=0, manual_max_y=None):\n    data = df[variable].values[start_index:start_index + num_values]\n\n    sleep_periods = []\n    start_idx, end_idx = None, None\n    start_value = None\n\n    for idx, value in enumerate(data):\n        if value >= level_of_change:\n            if start_idx is None:\n                start_idx = idx\n                start_value = value\n            end_idx = idx\n        elif start_idx is not None:\n            duration_seconds = (end_idx - start_idx + 1) * 5\n            if duration_seconds >= 30 * 60:\n                duration_hours = duration_seconds / 3600\n                sleep_periods.append((start_idx, end_idx, duration_hours, start_value, value))\n            start_idx, end_idx, start_value = None, None, None\n\n    etapes_en_heures = (df.index[start_index:start_index + num_values] - start_index) * 5 / 3600\n\n    plt.figure(figsize=(12, 6))\n    plt.plot(etapes_en_heures, df[variable][start_index:start_index + num_values], label=variable)\n    plt.xlabel('Heures')\n    plt.ylabel(f'Valeur de {variable}')\n\n    # Ajoutez les colonnes anglex, angley et anglez au graphique\n    plt.plot(etapes_en_heures, df['anglex'][start_index:start_index + num_values], label='anglex')\n    plt.plot(etapes_en_heures, df['angley'][start_index:start_index + num_values], label='angley')\n    plt.plot(etapes_en_heures, df['anglez'][start_index:start_index + num_values], label='anglez')\n\n    for start, end, _, start_value, end_value in sleep_periods:\n        plt.axvline(x=start * 5 / 3600, color='green', linestyle='--', label=f'Endormissement (Level: {start_value:.4f})')\n        plt.axvline(x=end * 5 / 3600, color='red', linestyle='--', label=f'Réveil (Level: {end_value:.4f}')\n\n    if manual_max_y is not None:\n        plt.ylim(0, manual_max_y)\n\n    plt.legend(loc=\"upper right\")\n    plt.grid(True)\n\n    print(\"Nombre de données traitées :\", len(data))\n\n    print(\"Moments d'endormissement et de réveil :\")\n    for start, end, duration, start_value, end_value in sleep_periods:\n        start_hours = start * 5 / 3600\n        end_hours = end * 5 / 3600\n        print(f\"Start: {start_hours} heures, End: {end_hours} heures, Durée: {duration} heures, Start Value: {start_value:.4f}, End Value: {end_value:.4f}\")\n\n    if sleep_periods:\n        durations = np.array([period[2] for period in sleep_periods])\n        total_sleep_hours = durations.sum()\n        print(f\"Total des heures de sommeil : {total_sleep_hours} heures\")\n        plt.show()\n    return sleep_periods\n\n# Nom de la variable\nvariable_name = 'enmo'\nlevel_of_change = 0.002  # Remplacez par la valeur réelle de changement d'état\nnum_values_to_take = 15000\nstart_index = 3000\nmanual_max_y = 0.5  # Remplacez par la valeur maximale que vous souhaitez\n\n# Appelez la fonction pour détecter les périodes de sommeil\nsleep_periods = detect_sleep_periods(df_train_series, variable_name, level_of_change, num_values_to_take, start_index, manual_max_y)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.1904Z","iopub.status.idle":"2023-11-06T19:11:00.190751Z","shell.execute_reply.started":"2023-11-06T19:11:00.190577Z","shell.execute_reply":"2023-11-06T19:11:00.190595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport matplotlib.pyplot as plt\n\n# Tronquer le DataFrame pour inclure uniquement les 20000 premières lignes\ndf_tronque = df_train_series.head(20000)\n\n# Créez un graphique pour anglez\nplt.figure(figsize=(12, 6))\nplt.plot(df_tronque['enmo'], label='enmo')\nplt.xlabel('Index')\nplt.ylabel('Valeur de enmo')\nplt.legend(loc=\"upper right\")\nplt.grid(True)\nplt.title('Graphique de enmo')\nplt.show()\n\n# Créez un graphique pour anglex\nplt.figure(figsize=(12, 6))\nplt.plot(df_tronque['anglex'], label='anglex')\nplt.xlabel('Index')\nplt.ylabel('Valeur de anglex')\nplt.legend(loc=\"upper right\")\nplt.grid(True)\nplt.title('Graphique de anglex')\nplt.show()\n\n# Créez un graphique pour angley\nplt.figure(figsize=(12, 6))\nplt.plot(df_tronque['angley'], label='angley')\nplt.xlabel('Index')\nplt.ylabel('Valeur de angley')\nplt.legend(loc=\"upper right\")\nplt.grid(True)\nplt.title('Graphique de angley')\nplt.show()\n\n# Créez un graphique pour anglez\nplt.figure(figsize=(12, 6))\nplt.plot(df_tronque['anglez'], label='anglez')\nplt.xlabel('Index')\nplt.ylabel('Valeur de anglez')\nplt.legend(loc=\"upper right\")\nplt.grid(True)\nplt.title('Graphique de anglez')\nplt.show()\n\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.192007Z","iopub.status.idle":"2023-11-06T19:11:00.192378Z","shell.execute_reply.started":"2023-11-06T19:11:00.192202Z","shell.execute_reply":"2023-11-06T19:11:00.19222Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_test_series():\n    fig, ax = plt.subplots(3,1, figsize=(10,8), sharex=True)\n    ax2 = {}\n    i = 0\n    test_series_list = list(test_series['series_id'].unique())\n    for id in test_series_list:\n        ax[i].set_title('series_id: ' + id, loc='left', fontsize=10)\n        x = test_series[test_series['series_id']==id]['step']\n        y_enmo = test_series[test_series['series_id']==id]['enmo']\n        y_anglez = test_series[test_series['series_id']==id]['anglez']\n        ax[i].plot(x, y_enmo, label='enmo', color='magenta', lw=1, alpha=0.9)\n        ax[i].set_ylabel('enmo', fontsize=9)\n        ax[i].tick_params(labelsize=9)\n        ax2[i] = ax[i].twinx()\n        ax2[i].plot(x, y_anglez, label='anglez', color='lime', lw=1, alpha=0.9)\n        ax2[i].set_ylabel('anglez', fontsize=9)\n        i = i + 1\n    h1, l1 = ax[2].get_legend_handles_labels()\n    h2, l2 = ax2[2].get_legend_handles_labels()\n    plt.figlegend(h1+h2, l1+l2, loc='upper left', bbox_to_anchor=(0.12, 0.97, 0.0, 0.0), ncols=2)\n    ax[2].set_xlabel('step')\n    plt.show()\n\n# Plot it\nplot_test_series()","metadata":{"execution":{"iopub.status.busy":"2023-11-06T19:11:00.194624Z","iopub.status.idle":"2023-11-06T19:11:00.195422Z","shell.execute_reply.started":"2023-11-06T19:11:00.19511Z","shell.execute_reply":"2023-11-06T19:11:00.195136Z"},"trusted":true},"execution_count":null,"outputs":[]}]}