757 lines
330 KiB
Plaintext
757 lines
330 KiB
Plaintext
|
|
{
|
|||
|
|
"cells": [
|
|||
|
|
{
|
|||
|
|
"cell_type": "markdown",
|
|||
|
|
"id": "e637deae-9168-4fb2-b95f-4e42d8d72d9e",
|
|||
|
|
"metadata": {},
|
|||
|
|
"source": [
|
|||
|
|
"# DATA COLLECTION "
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": null,
|
|||
|
|
"id": "f8508d94-74a7-4bb0-8b81-c2e06850c25f",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [],
|
|||
|
|
"source": [
|
|||
|
|
"import pandas as pd \n",
|
|||
|
|
"chemin_fichier = \"s3://projet-bdc-data/carmignac/AUM ENSAE V2 -20251105.csv\"\n",
|
|||
|
|
"df_aum2 = pd.read_csv(chemin_fichier, sep=';', engine='python')\n",
|
|||
|
|
"df_aum2"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": null,
|
|||
|
|
"id": "4644da13-5aea-4ca0-9fcf-947324766292",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [],
|
|||
|
|
"source": [
|
|||
|
|
"chemin_fichier = \"s3://projet-bdc-data/carmignac/Flows ENSAE V2 -20251105.csv\"\n",
|
|||
|
|
"df_flows2 = pd.read_csv(chemin_fichier, sep=';', engine='python')\n",
|
|||
|
|
"df_flows2"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "markdown",
|
|||
|
|
"id": "59d31eaf-c06c-4ebe-9f8c-cb9158a50976",
|
|||
|
|
"metadata": {},
|
|||
|
|
"source": [
|
|||
|
|
"## DATA ANALYSIS"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": null,
|
|||
|
|
"id": "5773b911-6b84-448d-962f-8228eeac0250",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [],
|
|||
|
|
"source": [
|
|||
|
|
"df_aum2.shape"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": null,
|
|||
|
|
"id": "6f571810-c373-4d30-8ca5-c3a074b95b08",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [],
|
|||
|
|
"source": [
|
|||
|
|
"df_aum2.columns"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": null,
|
|||
|
|
"id": "af25fd07-a613-4adc-b88b-93a8d300379c",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [],
|
|||
|
|
"source": [
|
|||
|
|
"df_flows2.shape"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": null,
|
|||
|
|
"id": "c6d0fe83-2957-430b-89cf-cd30833b7cab",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [],
|
|||
|
|
"source": [
|
|||
|
|
"df_flows2.columns"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "markdown",
|
|||
|
|
"id": "4ce2ad22-08e6-4e63-96b2-c2301172516e",
|
|||
|
|
"metadata": {},
|
|||
|
|
"source": [
|
|||
|
|
"# ETUDE ET ANALYSE DES ANOMALIES"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": null,
|
|||
|
|
"id": "c883dfc2-b9b9-4d3e-80d3-0140cd222492",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [],
|
|||
|
|
"source": [
|
|||
|
|
"df_aum2['Centralisation Date'] = pd.to_datetime(df_aum2['Centralisation Date'])\n",
|
|||
|
|
"df_flows2['Centralisation Date'] = pd.to_datetime(df_flows2['Centralisation Date'])\n",
|
|||
|
|
"\n",
|
|||
|
|
"\n",
|
|||
|
|
"key_cols = ['Registrar Account - ID', 'Product - Isin']"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": null,
|
|||
|
|
"id": "64ca9883-372b-4a5e-8fc1-10e5d835c411",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [],
|
|||
|
|
"source": [
|
|||
|
|
"# Vérifier doublons exacts\n",
|
|||
|
|
"doublons_aum = df_aum2[df_aum2.duplicated(subset=key_cols + ['Centralisation Date'], keep=False)]\n",
|
|||
|
|
"doublons_flows = df_flows2[df_flows2.duplicated(subset=key_cols + ['Centralisation Date'], keep=False)]\n",
|
|||
|
|
"\n",
|
|||
|
|
"print(\"Doublons AUM:\", doublons_aum.shape[0])\n",
|
|||
|
|
"print(\"Doublons Flows:\", doublons_flows.shape[0])\n",
|
|||
|
|
"\n",
|
|||
|
|
"#same date, code isin du produit, et account ==> revoir les autres caracteristiques "
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": null,
|
|||
|
|
"id": "f47b276d-cce6-433c-87c5-860810d71d34",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [],
|
|||
|
|
"source": [
|
|||
|
|
"cols= ['Company - Id', 'Company - Ultimate Parent Id',\n",
|
|||
|
|
" 'Registrar Account - ID', 'Registrar Account - Region','Product - Isin']\n",
|
|||
|
|
"\n",
|
|||
|
|
"doublons_aum2 = df_aum2[df_aum2.duplicated(subset=cols + ['Centralisation Date'], keep=False)]\n",
|
|||
|
|
"doublons_flows2 = df_flows2[df_flows2.duplicated(subset=cols + ['Centralisation Date'], keep=False)]\n",
|
|||
|
|
"\n",
|
|||
|
|
"print(\" Cols: \", cols)\n",
|
|||
|
|
"print(\"Doublons AUM:\", doublons_aum2.shape[0])\n",
|
|||
|
|
"print(\"Doublons Flows:\", doublons_flows2.shape[0])"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": null,
|
|||
|
|
"id": "8df98c34-b1f7-4fb9-bbc7-c9bbe762022a",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [],
|
|||
|
|
"source": [
|
|||
|
|
"df = df_flows2.copy()\n",
|
|||
|
|
"df[\"Date\"] = pd.to_datetime(df[\"Centralisation Date\"])\n",
|
|||
|
|
"\n",
|
|||
|
|
"# Groupby par ISIN et Date\n",
|
|||
|
|
"grouped = df.groupby([\"Product - Isin\", \"Date\"])\n",
|
|||
|
|
"\n",
|
|||
|
|
"transfers = []\n",
|
|||
|
|
"\n",
|
|||
|
|
"for (isin, date), group in grouped:\n",
|
|||
|
|
" # Sépare flux positifs et négatifs\n",
|
|||
|
|
" entrants = group[group[\"Value € - NetFlows\"] > 0][[\"Registrar Account - ID\", \"Value € - NetFlows\"]]\n",
|
|||
|
|
" sortants = group[group[\"Value € - NetFlows\"] < 0][[\"Registrar Account - ID\", \"Value € - NetFlows\"]]\n",
|
|||
|
|
"\n",
|
|||
|
|
" # On cherche des paires +M / -M\n",
|
|||
|
|
" for _, row_sortie in sortants.iterrows():\n",
|
|||
|
|
" montant_sortie = row_sortie[\"Value € - NetFlows\"]\n",
|
|||
|
|
" compte_sortant = row_sortie[\"Registrar Account - ID\"]\n",
|
|||
|
|
"\n",
|
|||
|
|
" # Chercher un +M qui matche exactement le -M\n",
|
|||
|
|
" match = entrants[entrants[\"Value € - NetFlows\"] == -montant_sortie]\n",
|
|||
|
|
"\n",
|
|||
|
|
" if len(match) > 0:\n",
|
|||
|
|
" for _, row_entree in match.iterrows():\n",
|
|||
|
|
" transfers.append({\n",
|
|||
|
|
" \"ISIN\": isin,\n",
|
|||
|
|
" \"Date\": date,\n",
|
|||
|
|
" \"Compte sortant\": compte_sortant,\n",
|
|||
|
|
" \"Montant sortie\": montant_sortie,\n",
|
|||
|
|
" \"Compte entrant\": row_entree[\"Registrar Account - ID\"],\n",
|
|||
|
|
" \"Montant entrée\": row_entree[\"Value € - NetFlows\"]\n",
|
|||
|
|
" })\n",
|
|||
|
|
"\n",
|
|||
|
|
"\n",
|
|||
|
|
"transf_compte = pd.DataFrame(transfers)\n",
|
|||
|
|
"transf_compte"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "markdown",
|
|||
|
|
"id": "c898b0c5-0a8e-4640-bc52-9490ee80e53d",
|
|||
|
|
"metadata": {},
|
|||
|
|
"source": [
|
|||
|
|
"# MERGE AND ANALYSIS"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": 8,
|
|||
|
|
"id": "ce33dbf8-1c59-416a-adc4-6eb7c1ea9d8e",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [
|
|||
|
|
{
|
|||
|
|
"name": "stdout",
|
|||
|
|
"output_type": "stream",
|
|||
|
|
"text": [
|
|||
|
|
"Merged dataset:\n"
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"source": [
|
|||
|
|
"import pandas as pd\n",
|
|||
|
|
"import numpy as np\n",
|
|||
|
|
"import matplotlib.pyplot as plt\n",
|
|||
|
|
"\n",
|
|||
|
|
"\n",
|
|||
|
|
"df_aum2 = df_aum2.rename(columns={\n",
|
|||
|
|
" \"Registrar Account - ID\": \"Account_ID\",\n",
|
|||
|
|
" \"Product - Isin\": \"ISIN\",\n",
|
|||
|
|
" \"Centralisation Date\": \"Date\",\n",
|
|||
|
|
" \"Value - AUM €\": \"AUM_EUR\"\n",
|
|||
|
|
"})\n",
|
|||
|
|
"\n",
|
|||
|
|
"df_flows2 = df_flows2.rename(columns={\n",
|
|||
|
|
" \"Registrar Account - ID\": \"Account_ID\",\n",
|
|||
|
|
" \"Product - Isin\": \"ISIN\",\n",
|
|||
|
|
" \"Centralisation Date\": \"Date\",\n",
|
|||
|
|
" \"Value € - NetFlows\": \"Flow_EUR\"\n",
|
|||
|
|
"})\n",
|
|||
|
|
"\n",
|
|||
|
|
"\n",
|
|||
|
|
"df_aum2[\"Date\"] = pd.to_datetime(df_aum2[\"Date\"])\n",
|
|||
|
|
"df_flows2[\"Date\"] = pd.to_datetime(df_flows2[\"Date\"])\n",
|
|||
|
|
"\n",
|
|||
|
|
"df_aum2[\"Account_ID\"] = df_aum2[\"Account_ID\"].astype(str)\n",
|
|||
|
|
"df_flows2[\"Account_ID\"] = df_flows2[\"Account_ID\"].astype(str)\n",
|
|||
|
|
"\n",
|
|||
|
|
"df_aum2[\"ISIN\"] = df_aum2[\"ISIN\"].str.upper()\n",
|
|||
|
|
"df_flows2[\"ISIN\"] = df_flows2[\"ISIN\"].str.upper()\n",
|
|||
|
|
"\n",
|
|||
|
|
"\n",
|
|||
|
|
"df_merged = pd.merge(\n",
|
|||
|
|
" df_aum2[[\"Account_ID\", \"ISIN\", \"Date\", \"AUM_EUR\"]],\n",
|
|||
|
|
" df_flows2[[\"Account_ID\", \"ISIN\", \"Date\", \"Flow_EUR\"]],\n",
|
|||
|
|
" on=[\"Account_ID\", \"ISIN\", \"Date\"],\n",
|
|||
|
|
" how=\"outer\"\n",
|
|||
|
|
").sort_values([\"Account_ID\", \"ISIN\", \"Date\"])\n",
|
|||
|
|
"\n",
|
|||
|
|
"print(\"Merged dataset:\")"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": 9,
|
|||
|
|
"id": "7e5d642e-5c16-4c78-8d83-075094902670",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [
|
|||
|
|
{
|
|||
|
|
"data": {
|
|||
|
|
"text/html": [
|
|||
|
|
"<div>\n",
|
|||
|
|
"<style scoped>\n",
|
|||
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|||
|
|
" vertical-align: middle;\n",
|
|||
|
|
" }\n",
|
|||
|
|
"\n",
|
|||
|
|
" .dataframe tbody tr th {\n",
|
|||
|
|
" vertical-align: top;\n",
|
|||
|
|
" }\n",
|
|||
|
|
"\n",
|
|||
|
|
" .dataframe thead th {\n",
|
|||
|
|
" text-align: right;\n",
|
|||
|
|
" }\n",
|
|||
|
|
"</style>\n",
|
|||
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|||
|
|
" <thead>\n",
|
|||
|
|
" <tr style=\"text-align: right;\">\n",
|
|||
|
|
" <th></th>\n",
|
|||
|
|
" <th>Account_ID</th>\n",
|
|||
|
|
" <th>ISIN</th>\n",
|
|||
|
|
" <th>Date</th>\n",
|
|||
|
|
" <th>AUM_EUR</th>\n",
|
|||
|
|
" <th>Flow_EUR</th>\n",
|
|||
|
|
" </tr>\n",
|
|||
|
|
" </thead>\n",
|
|||
|
|
" <tbody>\n",
|
|||
|
|
" <tr>\n",
|
|||
|
|
" <th>0</th>\n",
|
|||
|
|
" <td>100000014</td>\n",
|
|||
|
|
" <td>LU0553415323</td>\n",
|
|||
|
|
" <td>2015-01-31</td>\n",
|
|||
|
|
" <td>0.000000e+00</td>\n",
|
|||
|
|
" <td>NaN</td>\n",
|
|||
|
|
" </tr>\n",
|
|||
|
|
" <tr>\n",
|
|||
|
|
" <th>1</th>\n",
|
|||
|
|
" <td>100000014</td>\n",
|
|||
|
|
" <td>LU0553415323</td>\n",
|
|||
|
|
" <td>2015-02-28</td>\n",
|
|||
|
|
" <td>0.000000e+00</td>\n",
|
|||
|
|
" <td>NaN</td>\n",
|
|||
|
|
" </tr>\n",
|
|||
|
|
" <tr>\n",
|
|||
|
|
" <th>2</th>\n",
|
|||
|
|
" <td>100000014</td>\n",
|
|||
|
|
" <td>LU0553415323</td>\n",
|
|||
|
|
" <td>2015-03-31</td>\n",
|
|||
|
|
" <td>0.000000e+00</td>\n",
|
|||
|
|
" <td>NaN</td>\n",
|
|||
|
|
" </tr>\n",
|
|||
|
|
" <tr>\n",
|
|||
|
|
" <th>3</th>\n",
|
|||
|
|
" <td>100000014</td>\n",
|
|||
|
|
" <td>LU0553415323</td>\n",
|
|||
|
|
" <td>2015-04-30</td>\n",
|
|||
|
|
" <td>0.000000e+00</td>\n",
|
|||
|
|
" <td>NaN</td>\n",
|
|||
|
|
" </tr>\n",
|
|||
|
|
" <tr>\n",
|
|||
|
|
" <th>4</th>\n",
|
|||
|
|
" <td>100000014</td>\n",
|
|||
|
|
" <td>LU0553415323</td>\n",
|
|||
|
|
" <td>2015-05-31</td>\n",
|
|||
|
|
" <td>0.000000e+00</td>\n",
|
|||
|
|
" <td>NaN</td>\n",
|
|||
|
|
" </tr>\n",
|
|||
|
|
" <tr>\n",
|
|||
|
|
" <th>...</th>\n",
|
|||
|
|
" <td>...</td>\n",
|
|||
|
|
" <td>...</td>\n",
|
|||
|
|
" <td>...</td>\n",
|
|||
|
|
" <td>...</td>\n",
|
|||
|
|
" <td>...</td>\n",
|
|||
|
|
" </tr>\n",
|
|||
|
|
" <tr>\n",
|
|||
|
|
" <th>7369446</th>\n",
|
|||
|
|
" <td>Private Client</td>\n",
|
|||
|
|
" <td>LU2809794220</td>\n",
|
|||
|
|
" <td>2025-10-30</td>\n",
|
|||
|
|
" <td>NaN</td>\n",
|
|||
|
|
" <td>-1623.71</td>\n",
|
|||
|
|
" </tr>\n",
|
|||
|
|
" <tr>\n",
|
|||
|
|
" <th>7369447</th>\n",
|
|||
|
|
" <td>Private Client</td>\n",
|
|||
|
|
" <td>LU2809794220</td>\n",
|
|||
|
|
" <td>2025-10-31</td>\n",
|
|||
|
|
" <td>4.438147e+06</td>\n",
|
|||
|
|
" <td>4946.23</td>\n",
|
|||
|
|
" </tr>\n",
|
|||
|
|
" <tr>\n",
|
|||
|
|
" <th>7369448</th>\n",
|
|||
|
|
" <td>Private Client</td>\n",
|
|||
|
|
" <td>LU2809794576</td>\n",
|
|||
|
|
" <td>2025-09-23</td>\n",
|
|||
|
|
" <td>NaN</td>\n",
|
|||
|
|
" <td>71660.14</td>\n",
|
|||
|
|
" </tr>\n",
|
|||
|
|
" <tr>\n",
|
|||
|
|
" <th>7369449</th>\n",
|
|||
|
|
" <td>Private Client</td>\n",
|
|||
|
|
" <td>LU2809794576</td>\n",
|
|||
|
|
" <td>2025-09-30</td>\n",
|
|||
|
|
" <td>7.094499e+04</td>\n",
|
|||
|
|
" <td>NaN</td>\n",
|
|||
|
|
" </tr>\n",
|
|||
|
|
" <tr>\n",
|
|||
|
|
" <th>7369450</th>\n",
|
|||
|
|
" <td>Private Client</td>\n",
|
|||
|
|
" <td>LU2809794576</td>\n",
|
|||
|
|
" <td>2025-10-31</td>\n",
|
|||
|
|
" <td>7.871629e+04</td>\n",
|
|||
|
|
" <td>NaN</td>\n",
|
|||
|
|
" </tr>\n",
|
|||
|
|
" </tbody>\n",
|
|||
|
|
"</table>\n",
|
|||
|
|
"<p>7369451 rows × 5 columns</p>\n",
|
|||
|
|
"</div>"
|
|||
|
|
],
|
|||
|
|
"text/plain": [
|
|||
|
|
" Account_ID ISIN Date AUM_EUR Flow_EUR\n",
|
|||
|
|
"0 100000014 LU0553415323 2015-01-31 0.000000e+00 NaN\n",
|
|||
|
|
"1 100000014 LU0553415323 2015-02-28 0.000000e+00 NaN\n",
|
|||
|
|
"2 100000014 LU0553415323 2015-03-31 0.000000e+00 NaN\n",
|
|||
|
|
"3 100000014 LU0553415323 2015-04-30 0.000000e+00 NaN\n",
|
|||
|
|
"4 100000014 LU0553415323 2015-05-31 0.000000e+00 NaN\n",
|
|||
|
|
"... ... ... ... ... ...\n",
|
|||
|
|
"7369446 Private Client LU2809794220 2025-10-30 NaN -1623.71\n",
|
|||
|
|
"7369447 Private Client LU2809794220 2025-10-31 4.438147e+06 4946.23\n",
|
|||
|
|
"7369448 Private Client LU2809794576 2025-09-23 NaN 71660.14\n",
|
|||
|
|
"7369449 Private Client LU2809794576 2025-09-30 7.094499e+04 NaN\n",
|
|||
|
|
"7369450 Private Client LU2809794576 2025-10-31 7.871629e+04 NaN\n",
|
|||
|
|
"\n",
|
|||
|
|
"[7369451 rows x 5 columns]"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
"execution_count": 9,
|
|||
|
|
"metadata": {},
|
|||
|
|
"output_type": "execute_result"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"source": [
|
|||
|
|
"df_merged"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": 10,
|
|||
|
|
"id": "e484a3df-260e-4532-850b-3917592fcfdf",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [
|
|||
|
|
{
|
|||
|
|
"data": {
|
|||
|
|
"text/plain": [
|
|||
|
|
"Date 2025-11-28\n",
|
|||
|
|
"dtype: datetime64[ns]"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
"execution_count": 10,
|
|||
|
|
"metadata": {},
|
|||
|
|
"output_type": "execute_result"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"source": [
|
|||
|
|
"df_merged[['Date']].max() #2015-01-02 jusuqua 2025-11-28"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": 23,
|
|||
|
|
"id": "ea14866a-1ce6-4b19-9225-d725304af8ec",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [
|
|||
|
|
{
|
|||
|
|
"data": {
|
|||
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA2gAAAIjCAYAAAB2/jgmAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAW1dJREFUeJzt3Xt8z/X///H7e2MHh22GbVbDQs6HUMw5xtSQUiFyjGKLkWKVY0opQkT1CR3IqZLIWCOK5VRyllNUbCNsbcphe/3+6LvXz9tGe/OevfK+XS+X9+Xi/Xw+X6/X4/X2Lrvv+Xo9XzbDMAwBAAAAAAqcW0EXAAAAAAD4BwENAAAAACyCgAYAAAAAFkFAAwAAAACLIKABAAAAgEUQ0AAAAADAIghoAAAAAGARBDQAAAAAsAgCGgAAAABYBAENAJxgzJgxstlsN+VYLVq0UIsWLcz333zzjWw2m5YsWXJTjt+rVy+VL1/+phzreqWnp+uJJ55QUFCQbDabYmJibmh/V37mv/zyi2w2m+bOnXtD+wUA4EoENAC4wty5c2Wz2cyXl5eXgoODFRERoWnTpunPP/90ynGOHz+uMWPGaPv27U7ZnzNZuba8eOWVVzR37lwNGDBAH330kR5//PGCLum6vP3224TAfHTPPffIZrNp5syZufZn/+Ll1KlTufbXqFEj1+Bus9k0fvz4XLfp1q2bbDabihUrdsP1A7g1EdAA4CrGjRunjz76SDNnztTTTz8tSYqJiVHNmjW1Y8cOu7Evvvii/vrrL4f2f/z4cY0dO9bhELR69WqtXr3aoW0cda3a3nvvPe3fvz9fj3+j1qxZo4YNG2r06NHq3r276tWr59T9lytXTn/99Ve+Bz8CWv45cOCAtmzZovLly2vevHlO3beXl5c++eSTHO0ZGRn64osv5OXl5dTjAbi1ENAA4Cruu+8+de/eXb1791ZsbKxWrVqlr7/+WikpKerQoYNdICtUqFC+/9B17tw5SZKHh4c8PDzy9VjXUrhwYXl6ehbY8fMiJSVFfn5++bb/7JlVd3f3fDvGf5lhGA7/wuJm+/jjjxUQEKBJkyZp48aN+uWXX5y27/vvv1979uzRTz/9ZNf+xRdf6MKFC2rdurXTjgXg1kNAAwAHtGzZUiNHjtTRo0f18ccfm+253YMWHx+vJk2ayM/PT8WKFVPlypX1/PPPS/rnvrG7775bktS7d2/zsqjs2ZIWLVqoRo0a2rZtm5o1a6YiRYqY2155P1S2zMxMPf/88woKClLRokXVoUMH/frrr3Zjypcvr169euXY9vJ9/lttud2DlpGRoWeeeUYhISHy9PRU5cqV9cYbb8gwDLtxNptN0dHRWrp0qWrUqCFPT09Vr15dcXFxuX/gV0hJSVHfvn0VGBgoLy8v1a5dWx988IHZn30/3pEjR7RixQqz9n/74fvjjz/WPffcoyJFiqhEiRJq1qzZNWcpr3YP2r59+/Twww/L399fXl5eql+/vpYtW2Y3JvsS2g0bNmjo0KEqXbq0ihYtqgcffFAnT540x5UvX167d+/WunXrzPPI7e/9cm+88YYaNWqkkiVLytvbW/Xq1ctxb2KNGjV077335tg2KytLt912mx5++GG7tilTpqh69ery8vJSYGCgnnzySZ05c8Zu2/Lly6tdu3ZatWqV6tevL29vb73zzjuSpDlz5qhly5YKCAiQp6enqlWrluslhVlZWRozZoyCg4NVpEgR3XvvvdqzZ0+u39mzZ88qJibG/L5VrFhRr732mrKysq75+Vxu/vz5evjhh9WuXTv5+vpq/vz5ed7234SFhSk0NDTHPufNm6e2bdvK39/faccCcOshoAGAg7Iva7vWD/C7d+9Wu3btdP78eY0bN06TJk1Shw4dtGHDBklS1apVNW7cOElS//799dFHH+mjjz5Ss2bNzH388ccfuu+++1SnTh1NmTIl1x+qL/fyyy9rxYoVGj58uAYNGqT4+HiFh4c7PJORl9ouZxiGOnTooDfffFNt27bV5MmTVblyZT377LMaOnRojvHfffedBg4cqC5dumjixIn6+++/1alTJ/3xxx/XrOuvv/5SixYt9NFHH6lbt256/fXX5evrq169emnq1Klm7R999JFKlSqlOnXqmLWXLl36qvsdO3asHn/8cRUuXFjjxo3T2LFjFRISojVr1uT1I5P0z995w4YNtXfvXo0YMUKTJk1S0aJF1bFjR33++ec5xj/99NP66aefNHr0aA0YMEBffvmloqOjzf4pU6bo9ttvV5UqVczzeOGFF65Zw9SpU3XXXXdp3LhxeuWVV1SoUCE98sgjWrFihTmmc+fOWr9+vZKSkuy2/e6773T8+HF16dLFbHvyySf17LPPqnHjxpo6dap69+6tefPmKSIiQhcvXrTbfv/+/eratatat26tqVOnqk6dOpKkmTNnqly5cnr++ec1adIkhYSEaODAgZoxY4bd9rGxsRo7dqzq16+v119/XZUqVVJERIQyMjLsxp07d07NmzfXxx9/rB49emjatGlq3LixYmNjc/2+5WbTpk06ePCgunbtKg8PDz300ENOv8yxa9euWrBggflLilOnTmn16tV67LHHnHocALcgAwBgZ86cOYYkY8uWLVcd4+vra9x1113m+9GjRxuX/y/1zTffNCQZJ0+evOo+tmzZYkgy5syZk6OvefPmhiRj1qxZufY1b97cfL927VpDknHbbbcZaWlpZvuiRYsMScbUqVPNtnLlyhk9e/b8131eq7aePXsa5cqVM98vXbrUkGSMHz/ebtzDDz9s2Gw24+DBg2abJMPDw8Ou7aeffjIkGW+99VaOY11uypQphiTj448/NtsuXLhghIWFGcWKFbM793LlyhmRkZHX3J9hGMaBAwcMNzc348EHHzQyMzPt+rKyssw/X/n5HDlyJMfn06pVK6NmzZrG33//bbePRo0aGZUqVTLbsr9f4eHhdscYMmSI4e7ubpw9e9Zsq169ut1x/825c+fs3l+4cMGoUaOG0bJlS7Nt//79uX7eAwcONIoVK2bu49tvvzUkGfPmzbMbFxcXl6O9XLlyhiQjLi7uX2syDMOIiIgw7rjjDvN9UlKSUahQIaNjx45248aMGWNIsvvOvvTSS0bRokWNn3/+2W7siBEjDHd3d+PYsWM5jnel6OhoIyQkxPz8V69ebUgyfvzxR7tx2f9dX+2/4yv/frK/F6+//rqxa9cuQ5Lx7bffGoZhGDNmzDCKFStmZGRkGD179jSKFi36r3UCcE3MoAHAdShWrNg1V3PMvv/piy++cOiyq8t5enqqd+/eeR7fo0cPFS9e3Hz/8MMPq0yZMvrqq6+u6/h59dVXX8nd3V2DBg2ya3/mmWdkGIZWrlxp1x4eHq4KFSqY72vVqiUfHx8dPnz4X48TFBSkrl27mm2FCxfWoEGDlJ6ernXr1jlc+9KlS5WVlaVRo0bJzc3+n0RHHptw+vRprVmzRo8++qj+/PNPnTp1SqdOndIff/yhiIgIHThwQL///rvdNv3797c7RtOmTZWZmamjR486fB7ZvL29zT+fOXNGqampatq0qX744Qez/c4771SdOnW0cOFCsy0zM1NLlixR+/btzX0sXrxYvr6+at26tXk+p06dUr169VSsWDGtXbvW7tihoaGKiIi4Zk2pqak6deqUmjdvrsOHDys1NVWSlJCQoEuXLmngwIF222YvznO5xYsXq2nTpipRooRdXeHh4crMzNT69euv+RldunRJCxcuVOfOnc3PP/sSTGfOolWvXl21atUyFwuZP3++HnjgARUpUsRpxwBwayKgAcB1SE9PtwtDV+rcubMaN26sJ554QoGBgerSpYsWLVrkUFi77bbbHFoMpFKlSnbvbTabKlas6NTFD3Jz9OhRBQcH5/g8qlatavZfrmzZsjn2UaJEiRz3NeV2nEqVKuUIUlc7Tl4cOnRIbm5uqlatmsPbXu7gwYMyDEMjR45U6dKl7V6jR4+W9M/9c5e78nMoUaKEJP3r53Aty5cvV8OGDeXl5SV/f3+VLl1aM2fONINQts6dO2vDhg1maPz
|
|||
|
|
"text/plain": [
|
|||
|
|
"<Figure size 1000x600 with 1 Axes>"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
"metadata": {},
|
|||
|
|
"output_type": "display_data"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"source": [
|
|||
|
|
"# 2. HISTOGRAMME DES AUM (SANS ISIN)\n",
|
|||
|
|
"# We keep the mean AUM per Account \n",
|
|||
|
|
"aum_by_account = (\n",
|
|||
|
|
" df_merged.groupby(\"Account_ID\")[\"AUM_EUR\"]\n",
|
|||
|
|
" .mean()\n",
|
|||
|
|
" .dropna()\n",
|
|||
|
|
")\n",
|
|||
|
|
"plt.figure(figsize=(10,6))\n",
|
|||
|
|
"plt.hist(aum_by_account, bins=100)\n",
|
|||
|
|
"# ZOOM sur les petits AUM (0 à 0.5M €)\n",
|
|||
|
|
"plt.xlim(0, 0.5e7)\n",
|
|||
|
|
"plt.xlabel(\"Mean AUM value (€)\")\n",
|
|||
|
|
"plt.ylabel(\"Number of client accounts\")\n",
|
|||
|
|
"plt.title(\"Distribution of client average AUM \")\n",
|
|||
|
|
"plt.show()"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": 40,
|
|||
|
|
"id": "8d0dec63-9b9a-47ea-90bd-ffe059bb232a",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [
|
|||
|
|
{
|
|||
|
|
"data": {
|
|||
|
|
"image/png": "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nUWflNNodu7cqWHDhqlgwYJydnZWu3btdOnSJXO/YsWK6eDBg9q2bZt5P9L6vt/vgw8+UJ06dZQ/f345OjqqevXqqa4FrFChgho3bpxq3eTkZBUuXFgdO3a0aJs5c6bKly+v3Llzy9PTU6+++qquXbtmsW6xYsXUqlUrbdiwQTVq1JCjo6M+/fRTSdKCBQvUpEkTeXh4yMHBQf7+/mme5pecnKxx48bJ29tbTk5Oaty4sQ4dOpTme/b69esKDQ01v99KliypKVOmWHXNzZIlS9SxY0e1atVKbm5uWrJkSbrXfZyAgAD5+fmlGnPx4sVq0aKF3N3d0zVOz5495eLiopMnTyooKEjOzs7y9vbWhAkTUv1sZcb3Ki0//fSTXnzxRRUtWlQODg7y8fHR0KFDdevWrVR9jxw5ok6dOqlgwYJydHRUmTJl9Pbbb1v0+euvv9SnTx95e3vLwcFBfn5+GjhwoO7cuWPuc/LkSb344otyd3eXk5OTateurbVr11qMk/Jz9ODPdspnwNatW81tKZ+nhw4dUuPGjeXk5KTChQtr6tSpFus96nMvLadOndK+ffsUGBho0e7n5ydfX1+LNpPJpLZt2yoxMdHiNLyVK1cqR44c6t+/v7ktd+7c6tOnjyIjI82f4QUKFFD58uVT1dCuXTtJ0uHDh81t1atXT3Vaa/78+VW/fn2LfulhzVgrV67Uc889Z34dJals2bJq2rSpli9fbm4rX768ChQoYLGug4ODnn/+ef35558PPbX/xo0bqU6xfFCzZs30/fffp/r5ADIb4QuwoZTrhx71x/nBgwfVqlUrJSYmasKECZo+fbratGmjnTt3SpLKlSunCRMmSJL69++vL7/8Ul9++aUaNGhgHuPKlStq2bKlqlSpopkzZ6b5B/P93nvvPa1du1ajRo3SkCFDFBERocDAwDT/SHqU9NR2P8Mw1KZNG3344Ydq0aKFZsyYoTJlyuiNN97QsGHDUvXfsWOHXnvtNXXp0kVTp07V7du31aFDB125cuWRdd26dUuNGjXSl19+qW7dumnatGlyc3NTz549NWvWLHPtX375pQoUKKAqVaqYay9YsOBDxx0/frxeeeUV5cqVSxMmTND48ePl4+OjzZs3p/clk/T397x27do6fPiw3nzzTU2fPl3Ozs5q27atVq1alar/4MGD9fvvv2vs2LEaOHCgvv/+ew0aNMi8fObMmSpSpIjKli1r3o8H/5B90KxZs1S1alVNmDBB77//vnLmzKkXX3zR4g/Xzp07a/v27RbXS0h/f1/Onz+vLl26mNteffVVvfHGG6pbt65mzZqlXr16afHixQoKCtLdu3ct1j969Ki6du2qZs2aadasWapSpYokae7cufL19dVbb72l6dOny8fHR6+99prmzJljsX5YWJjGjx+vGjVqaNq0aSpVqpSCgoKUkJBg0e/mzZtq2LChvvrqK3Xv3l0fffSR6tatq7CwsDTfb2n5+eefdfz4cXXt2lX29vZq3769Fi9enK5106tr165aunSp+Y/Ay5cva+PGjXrppZesGicpKUktWrSQp6enpk6dqurVq2vs2LEaO3asRb/M+F6lZcWKFbp586YGDhyojz/+WEFBQfr444/VvXt3i3779u1TrVq1tHnzZvXr10+zZs1S27Zt9f3335v7nD9
|
|||
|
|
"text/plain": [
|
|||
|
|
"<Figure size 1000x600 with 1 Axes>"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
"metadata": {},
|
|||
|
|
"output_type": "display_data"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"source": [
|
|||
|
|
"# 2. HISTOGRAMME DES AUM (SANS ISIN) POUR 2022+\n",
|
|||
|
|
"df_filtered = df_merged[df_merged[\"Date\"].dt.year >= 2022]\n",
|
|||
|
|
"\n",
|
|||
|
|
"aum_by_account = (\n",
|
|||
|
|
" df_filtered\n",
|
|||
|
|
" .groupby(\"Account_ID\")[\"AUM_EUR\"]\n",
|
|||
|
|
" .mean()\n",
|
|||
|
|
" .dropna()\n",
|
|||
|
|
")\n",
|
|||
|
|
"\n",
|
|||
|
|
"plt.figure(figsize=(10,6))\n",
|
|||
|
|
"plt.hist(aum_by_account, bins=100)\n",
|
|||
|
|
"\n",
|
|||
|
|
"# ZOOM sur les petits AUM (0 à 5M €)\n",
|
|||
|
|
"plt.xlim(0, 0.5e7)\n",
|
|||
|
|
"\n",
|
|||
|
|
"plt.xlabel(\"Mean AUM value (€)\")\n",
|
|||
|
|
"plt.ylabel(\"Number of client accounts\")\n",
|
|||
|
|
"plt.title(\"Distribution of client average AUM per account (2022–2025)\")\n",
|
|||
|
|
"plt.show()\n"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": 9,
|
|||
|
|
"id": "f13c213e-7f72-494a-bcf0-b4cd9feee55d",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [
|
|||
|
|
{
|
|||
|
|
"name": "stdout",
|
|||
|
|
"output_type": "stream",
|
|||
|
|
"text": [
|
|||
|
|
"Monthly flow summary:\n",
|
|||
|
|
" n_positive_flows n_negative_flows\n",
|
|||
|
|
"YearMonth \n",
|
|||
|
|
"2015-01 10688 11779\n",
|
|||
|
|
"2015-02 12905 10822\n",
|
|||
|
|
"2015-03 15497 13207\n",
|
|||
|
|
"2015-04 13838 11641\n",
|
|||
|
|
"2015-05 11143 9065\n"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"data": {
|
|||
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAABW0AAAJOCAYAAADMCCWlAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAtZhJREFUeJzs3Wd0VFX79/HfBEghpBBaiEaI9BI6YoAUFA29ShFuBUS4VZCOiCLNgvSqIBaKEkGKqKBA6KGItEjvEbiFgAIh0lPO84In5++QQgYmheT7WStrMXvvs891zswk4cqea1sMwzAEAAAAAAAAAMgWHLI6AAAAAAAAAADA/yFpCwAAAAAAAADZCElbAAAAAAAAAMhGSNoCAAAAAAAAQDZC0hYAAAAAAAAAshGStgAAAAAAAACQjZC0BQAAAAAAAIBshKQtAAAAAAAAAGQjJG0BAAAAAAAAIBshaQsAALIti8Wi3r1733fc3LlzZbFY9Mcff2R8UFlk5MiRslgs+vvvv7M6lHTZuXOn6tatK1dXV1ksFkVGRmZ1SPiXrl27qmTJkukeW6BAgQc+V0hIiEJCQh74+K+//lrly5dXvnz55OnpaZc58WBSel8nfW8CAAD2RdIWAIBcKCnJabFYtGXLlmT9hmHI19dXFotFzZo1y9BYtm3bppEjRyomJiZDz4PMExcXp3bt2uny5cuaPHmyvv76a5UoUSKrw8oWPv30U82dOzerw0jmxo0bGjlypDZu3JjVoVg5cuSIunbtqlKlSunzzz/X7NmzszqkHO+jjz7S8uXLk7XzvgYAIHPlzeoAAABA1nF2dlZYWJjq169v1b5p0yb973//k5OTU4bHsG3bNo0aNUpdu3Y1V9Hh0Xby5EmdPn1an3/+uV599dWsDidb+fTTT1W4cGF17do1S+P4/PPPlZiYaD6+ceOGRo0aJUl2X8G6Zs2aBz5248aNSkxM1NSpU1W6dGk7RoXUfPTRR3rhhRfUqlUrq3be1wAAZC5W2gIAkIs1adJEixcvVnx8vFV7WFiYatasKW9v7yyKDFnlxo0bDz3HxYsXJYkkfDaWL1++TPmjjCQ5OjrK0dHxgY7ltZR98FwAAJC5SNoCAJCLvfjii7p06ZLCw8PNtjt37mjJkiXq1KlTisdcv35dAwcOlK+vr5ycnFSuXDlNmDBBhmFYjUuqR7t8+XJVrlxZTk5OqlSpklatWmWOGTlypAYPHixJ8vPzM0s23FubNq05UtKlSxcVLlxYcXFxyfqef/55lStXLs3jQ0JCVLlyZR06dEgNGjRQ/vz59dhjj2ncuHFW41Krpbtx40ZZLBarj5onzblv3z4FBwcrf/78Kl26tJYsWSLp7urmOnXqyMXFReXKldPatWtTjO3vv/9W+/bt5e7urkKFCqlv3766detWsnHffPONatasKRcXF3l5ealjx446e/Zsite5e/duBQUFKX/+/HrnnXfSvDfr169XYGCgXF1d5enpqZYtW+rw4cNmf9euXRUcHCxJateunSwWS5orNy9fvqxBgwbJ399fBQoUkLu7uxo3bqzff/892dhbt25p5MiRKlu2rJydnVW8eHG1adNGJ0+eNMckrcr09/eXs7OzihQpokaNGmnXrl3mmPj4eL3//vsqVaqUnJycVLJkSb3zzju6ffu21fksFotGjhyZLI6SJUtarZRNeh1s3bpVAwYMUJEiReTq6qrWrVvrr7/+sjru4MGD2rRpk/laT7o3cXFxGjVqlMqUKSNnZ2cVKlRI9evXt3pv3ismJkZ58uTRtGnTzLa///5bDg4OKlSokNV78vXXX7f6I8y/a9r+8ccfKlKkiCRp1KhRZmz3Xvuff/6pVq1aqUCBAipSpIgGDRqkhISEVONLcm/92aT3x3fffacPP/xQjz/+uJydnfXss8/qxIkTVvdrxIgRkqQiRYqk+nwkuXjxorp3765ixYrJ2dlZVatW1bx586zG1KhRQ23atLFq8/f3l8Vi0b59+8y2RYsWyWKxmK/tf/75R/369VPJkiXl5OSkokWL6rnnntOePXtSjWfJkiWyWCzatGlTsr7PPvtMFotFBw4ckCRFR0erW7duevzxx+Xk5KTixYurZcuW6arTfb/3pJR6DeN769FaLBZdv35d8+bNM18HXbt2tfl9nZ732IABA5K9Tt98801ZLBar1/SFCxdksVg0c+ZMs2369OmqVKmS8ufPr4IFC6pWrVoKCwu7770CAOBRQtIWAIBcrGTJkgoICNC3335rtv3yyy+6evWqOnbsmGy8YRhq0aKFJk+erEaNGmnSpEkqV66cBg8erAEDBiQbv2XLFr3xxhvq2LGjxo0bp1u3bqlt27a6dOmSJKlNmzZ68cUXJcmskfj111+bCaT0zJGSl156SZcuXdLq1aut2qOjo7V+/Xr95z//ue+9uXLliho1aqSqVatq4sSJKl++vIYMGaJffvnlvsemNWezZs1Up04djRs3Tk5OTurYsaMWLVqkjh07qkmTJvr44491/fp1vfDCC/rnn3+SzdG+fXvdunVLY8aMUZMmTTRt2jT17NnTasyHH36ol19+WWXKlNGkSZPUr18/rVu3TkFBQclqB1+6dEmNGzdWtWrVNGXKFDVo0CDV+NeuXavQ0FBdvHhRI0eO1IABA7Rt2zbVq1fPTC7997//NRO/ffr00ddff61333031TlPnTql5cuXq1mzZpo0aZIGDx6s/fv3Kzg4WOfOnTPHJSQkqFmzZho1apRq1qypiRMnqm/fvrp69aqZ+JKk7t27q1+/fvL19dXYsWP19ttvy9nZWb/++qs55tVXX9Xw4cNVo0YNTZ48WcHBwRozZkyKr3lbvPnmm/r99981YsQIvf766/rpp5+sNtKbMmWKHn/8cZUvX958rSfdm5EjR2rUqFFq0KCBZsyYoXfffVdPPPFEmklBT09PVa5cWZs3bzbbtmzZIovFosuXL+vQoUNme0REhAIDA1Ocp0iRImZCrHXr1mZs/05uJiQkKDQ0VIUKFdKECRMUHBysiRMnPlSN2Y8//ljff/+9Bg0apKFDh+rXX39V586dzf4pU6aodevWkqSZM2cmi+nfbt68qZCQEH399dfq3Lmzxo8fLw8PD3Xt2lVTp041xwUGBlrV8b58+bIOHjwoBwcHRUREmO0REREqUqSIKlSoIEl67bXXNHPmTLVt21affvqpBg0aJBcXl2TJ0X9r2rSpChQooO+++y5Z36JFi1SpUiVVrlxZktS2bVt9//336tatmz799FP16dNH//zzj86cOZPmPUzPe9IWX3/9tZycnBQYGGi+Dv773//a/L5Oz3ssMDDQvP9JIiIiUnwuJCkoKEjS3dIeffr0UcWKFTVlyhSNGjVK1apV044dO2y+XgAAsjUDAADkOnPmzDEkGTt37jRmzJhhuLm5GTdu3DAMwzDatWtnNGjQwDAMwyhRooTRtGlT87jly5cbkowPPvjAar4XXnjBsFgsxokTJ8w2SYajo6NV2++//25IMqZPn262jR8/3pBkREVFJYszvXMkXU/SHAkJCcbjjz9udOjQwWq+SZMmGRaLxTh16lSa9yc4ONiQZMyfP99su337tuHt7W20bds21fMm2bBhgyHJ2LBhQ7I5w8LCzLYjR44YkgwHBwfj119/NdtXr15tSDLmzJljto0YMcKQZLRo0cLqXG+88YYhyfj9998NwzCMP/74w8iTJ4/x4YcfWo3bv3+/kTdvXqv2pJhmzZqV5v1IUq1aNaNo0aLGpUuXzLbff//dcHBwMF5++eVk17948eL7znnr1i0jISHBqi0qKspwcnIyRo8ebbZ99dVXhiRj0qRJyeZITEw0DMMw1q9fb0gy+vTpk+qYyMhIQ5Lx6quvWvUPGjTIkGSsX7/ebJNkjBgxItlcJUqUMLp06WI+TnodNGzY0DyPYRhG//79jTx58hgxMTFmW6VKlYzg4OBkc1atWtXqvZZevXr1MooVK2Y+HjBggBEUFGQULVrUmDlzpmEYhnHp0iXDYrEYU6dONcd16dLFKFGihPn4r7/+SvV6u3TpYkiyej4MwzC
|
|||
|
|
"text/plain": [
|
|||
|
|
"<Figure size 1400x600 with 1 Axes>"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
"metadata": {},
|
|||
|
|
"output_type": "display_data"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"source": [
|
|||
|
|
"# ANALYSE MENSUELLE DES FLOWS (ENTRANTS / SORTANTS)\n",
|
|||
|
|
"\n",
|
|||
|
|
"df_merged[\"YearMonth\"] = df_merged[\"Date\"].dt.to_period(\"M\")\n",
|
|||
|
|
"\n",
|
|||
|
|
"flows_monthly = df_merged.groupby(\"YearMonth\").agg(\n",
|
|||
|
|
" n_positive_flows=(\"Flow_EUR\", lambda x: (x > 0).sum()),\n",
|
|||
|
|
" n_negative_flows=(\"Flow_EUR\", lambda x: (x < 0).sum()),\n",
|
|||
|
|
")\n",
|
|||
|
|
"\n",
|
|||
|
|
"print(\"Monthly flow summary:\")\n",
|
|||
|
|
"print(flows_monthly.head())\n",
|
|||
|
|
"\n",
|
|||
|
|
"flows_monthly.index = flows_monthly.index.astype(str)\n",
|
|||
|
|
"plt.figure(figsize=(14,6))\n",
|
|||
|
|
"plt.bar(flows_monthly.index, flows_monthly[\"n_positive_flows\"], label=\"Positive flows (inflows)\", alpha=0.7)\n",
|
|||
|
|
"plt.bar(flows_monthly.index, flows_monthly[\"n_negative_flows\"], label=\"Negative flows (outflows)\", alpha=0.7)\n",
|
|||
|
|
"plt.xticks(rotation=90)\n",
|
|||
|
|
"plt.xlabel(\"Year-Month\")\n",
|
|||
|
|
"plt.ylabel(\"Number of accounts with flows\")\n",
|
|||
|
|
"plt.title(\"Monthly number of accounts with inflows vs outflows\")\n",
|
|||
|
|
"plt.legend()\n",
|
|||
|
|
"plt.tight_layout()\n",
|
|||
|
|
"plt.show()\n"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": 14,
|
|||
|
|
"id": "4af0e205-a304-4b10-be1d-de69904aa0da",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [
|
|||
|
|
{
|
|||
|
|
"data": {
|
|||
|
|
"image/png": "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goIC9OvXT35OJ0yYAF9fX7zzzjt4++23MWDAgCoFdVOWLFmCu+66CwsXLsRbb70FJycnjBkzBps2baqyrSVfw6dOncLQoUORkZGB+fPnY9q0aZg3bx5++eWXGtcC6AvpY8eOhVKpxKJFi/DEE0/g559/Rp8+fWr9WgYGBmLp0qUAgIceekj+vvzHP/6BV199FdOnTwcALFy4EN9++y3++c9/mtyPpe8Xffv2xYkTJ5CXlyc/bt++fVVeP+k1veeeewDovzYWLFiAgQMH4uOPP8arr76K5s2b4+jRo7X6fImIiKiBiERERERUxfLly0UA4qFDh8SPP/5Y9PT0FIuKikRRFMUxY8aIAwcOFEVRFFu0aCEOHz5cftz69etFAOK///1vo/2NHj1aFARBvHjxonwbAFGlUhndduLECRGA+NFHH8m3vfvuuyIAMSkpqco6Ld2H9PlI+9BqtWKzZs3EcePGGe1v8eLFoiAI4uXLl6t9fqTnoqJFixaJgiCIV65ckW/r1auXGBMTY7RdfHy8CEBcuXKlKIqiqNPpxMjISDE2NlbU6XRGx4iIiBCHDBki3zZv3jwRgDhhwgSL1rR69WoRgPjXX3/Jt40YMUJ0c3MTr127Jt924cIF0cnJSaz463FycrKoVCrFN99802ifp06dEp2cnKrcXlnl51wU9V8vldeTkZEhqtVq8YUXXpBvS0pKEgGI7777brX7zMjIEFUqlTh06FBRq9XK23388cciAPHrr78WRVH/ent5eYkvvfSSKIr659zf318cM2aMqFQqxfz8fFEU9a+/QqEQb968KYqiKD7//POil5eXWF5eXu3nakrl10Oj0YjR0dHioEGDjG639Gt45MiRoouLi9HXV0JCgqhUKsWa/qzRaDRiUFCQGB0dLRYXF8u3//bbbyIA8fXXX5dv69+/v9i/f/8q+5gyZYrYokUL+eMbN26IAMR58+ZV2bbi+0d1+7D0/eLQoUMiAPH3338XRVEUT548KQIQx4wZI959993y4x544AHxrrvukj/u3Lmz0fsTERERNS7suCUiIiKqwdixY1FcXIzffvsN+fn5+O2338zGJPz+++9QKpV47rnnjG5/4YUXIIqifAmzZPDgwWjVqpX8cadOneDl5YXLly9bvL667EOhUGDixInYsGED8vPz5du///579O7dGxEREdUe09XVVf7/wsJCZGZmonfv3hBFEceOHZPvGzduHI4cOYJLly7Jt61duxZqtRoPPvggAOD48eO4cOECHn74YWRlZSEzMxOZmZkoLCzEvffei7/++gs6nc7o+E8++WS1ayopKUFmZiZ69uwJAHKHoVarxfbt2zFy5Eg0adJE3r5169YYNmyY0f5+/vln6HQ6jB07Vl5TZmYmQkJCEBkZiT///LPa58icqKgo9O3bV/44MDAQbdu2rdVrLtm+fTs0Gg1mzpwJheLWr/ZPPPEEvLy85O5WhUKB3r1746+//gIAnD17FllZWXj55ZchiiIOHDgAQN+xGR0dLWez+vj4oLCwsE6X1ld8PW7evInc3Fz07dvXZLdnTV/DWq0WW7duxciRI9G8eXN5u/bt2yM2NrbGtRw+fBgZGRl4+umn4eLiIt8+fPhwtGvXzmQXsD1Y+n5x1113wcPDQ3799uzZg2bNmmHy5Mk4evQoioq
|
|||
|
|
"text/plain": [
|
|||
|
|
"<Figure size 1400x600 with 1 Axes>"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
"metadata": {},
|
|||
|
|
"output_type": "display_data"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"source": [
|
|||
|
|
"df_merged[\"YearMonth\"] = df_merged[\"Date\"].dt.to_period(\"M\")\n",
|
|||
|
|
"\n",
|
|||
|
|
"monthly_flow_amounts = df_merged.groupby(\"YearMonth\").agg(\n",
|
|||
|
|
" avg_positive_flow=(\"Flow_EUR\", lambda x: x[x > 0].mean()),\n",
|
|||
|
|
" avg_negative_flow=(\"Flow_EUR\", lambda x: x[x < 0].mean())\n",
|
|||
|
|
")\n",
|
|||
|
|
"\n",
|
|||
|
|
"monthly_flow_amounts.index = monthly_flow_amounts.index.astype(str)\n",
|
|||
|
|
"\n",
|
|||
|
|
"plt.figure(figsize=(14,6))\n",
|
|||
|
|
"plt.plot(monthly_flow_amounts.index, monthly_flow_amounts[\"avg_positive_flow\"], label=\"Average inflow (positive)\", marker=\"o\")\n",
|
|||
|
|
"plt.plot(monthly_flow_amounts.index, monthly_flow_amounts[\"avg_negative_flow\"], label=\"Average outflow (negative)\", marker=\"o\")\n",
|
|||
|
|
"plt.xticks(rotation=90)\n",
|
|||
|
|
"plt.xlabel(\"Year-Month\")\n",
|
|||
|
|
"plt.ylabel(\"Average flow (€)\")\n",
|
|||
|
|
"plt.title(\"Monthly average inflows and outflows\")\n",
|
|||
|
|
"plt.legend()\n",
|
|||
|
|
"plt.tight_layout()\n",
|
|||
|
|
"plt.show()\n"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": 15,
|
|||
|
|
"id": "2d548152-196f-456a-b21e-4d05e39d03c5",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [
|
|||
|
|
{
|
|||
|
|
"data": {
|
|||
|
|
"image/png": "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tXfvXs2dO9c6T7fddpvq1aunUaNGycvLS/v379eqVasu2IckjRw5UnFxcWrWrJlGjRolT09PrV27VkuWLFHr1q0v+voseb1WHnnkERUvXlwjRozQgQMHNGnSJA0cOFAfffSRJGnSpEnnPc9xcXEaM2aM+vTpo8aNGyslJUUbNmzQjz/+qJtvvvmivV6J6/RCMjIy1KZNGzVp0kQvv/yyvvvuO40fP16VK1fWQw89lONr2rVrJ39/f3388cdWOJnlo48+Uu3atVWnTp08nYuff/5Zc+fOVefOnRUREaGkpCS98cYbio6O1s6dOxUeHn7RY5kb27ZtU+vWrVW6dGnFxcXpzJkzGjFiRI7H6fnnn9ewYcPUpUsX9enTR4cOHdKUKVPUsmVLbdq06byjaPv3768yZcrohRde0KOPPqpGjRpd9DxcjI+Pj9555x1FRUXpmWee0YQJEyRJAwYM0LFjxzRz5ky5ublddDuPPPKIQkNDNXLkSP3www+aPn26goKCtHr1apUvX14vvPCCvvnmG7300kuqU6eOunfv7rJfM2fOVK9evfToo48qISFBr776qjZt2qRVq1a5TFGyf/9+3XXXXerdu7d69OihGTNmqGfPnoqMjFTt2rUlXf69c6689AcAACQZAACA84iPjzeSzHfffWcOHTpkfv31V/PJJ5+Y0qVLGy8vL/Prr79ata1atTJ169Y1p0+ftpZlZmaaZs2amapVq2bbZmRkpElLS7OWjxs3zkgyX3zxhbXs5MmT2Xrq37+/8fX1dXmf6OhoI8lMmzYtW33t2rVNdHR0tuVLly41kszSpUutZe3atTMVKlTIVpuQkGAkmfj4eGtZ/fr1TXBwsDl8+LC1bMuWLcbpdJru3btby0aMGGEkmQceeMBlm3fccYcpWbJktvc6W1pamgkODjb169c3qamp1vLp06cbSS779d577xmn02m+//57l21MmzbNSDKrVq0yxhgzceJEI8kcOnTogu99rn379hmn02nuuOMOk5GR4bIuMzPT+nd0dLRLXzkdu7xeK7GxsS7v8fjjjxs3Nzdz9OhRa9n5zvN1111n2rVrl6d9Pfu9r9R1mpMePXoYSWbUqFEuyxs0aGAiIyNdlkkyI0aMsJ7fc889Jjg42Jw5c8Za9ueffxqn0+myvdyei9OnT2c77wkJCcbLy8tle1nHLSEhwaU2p/stJx07djTe3t7ml19+sZbt3LnTuLm5mbP/dDlw4IBxc3Mzzz//vMvrt23bZtzd3bMtP1dWP3PmzHFZnnW/nr2P516/Wc495sYYM3ToUON0Os2KFSvMnDlzjCQzadKkC/ZizP+OW5s2bVyu9aZNmxqHw2EefPBBa9mZM2dM2bJlXa7377//3kgys2bNctnu/Pnzsy2vUKGCkWRWrFhhLUtOTjZeXl7mP//5j7UsN/fOufd7lh49erh8lualv/NtEwCAoobpEQAAwEXFxsaqdOnSKleunO666y75+fnpyy+/VNmyZSX9+58AL1myRF26dNE///yjv/76S3/99ZcOHz6sNm3aaN++ffr9999dttmvXz+XkVUPPfSQ3N3d9c0331jLfHx8rH9nbbdFixY6efKkdu/e7bI9Ly8v9erVqyB2P5s///xTmzdvVs+ePVWiRAlreb169XTzzTe77EOWBx980OV
|
|||
|
|
"text/plain": [
|
|||
|
|
"<Figure size 1400x600 with 1 Axes>"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
"metadata": {},
|
|||
|
|
"output_type": "display_data"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"source": [
|
|||
|
|
"df = df_merged.copy()\n",
|
|||
|
|
"df[\"YearMonth\"] = df[\"Date\"].dt.to_period(\"M\")\n",
|
|||
|
|
"\n",
|
|||
|
|
"# 1) Flow mensuel total par client\n",
|
|||
|
|
"monthly_client_flow = (\n",
|
|||
|
|
" df.groupby([\"Account_ID\", \"YearMonth\"])[\"Flow_EUR\"]\n",
|
|||
|
|
" .sum()\n",
|
|||
|
|
" .reset_index()\n",
|
|||
|
|
")\n",
|
|||
|
|
"\n",
|
|||
|
|
"# 2) Calcul des seuils de quantiles (tu peux ajuster)\n",
|
|||
|
|
"q1 = monthly_client_flow[\"Flow_EUR\"].quantile(0.33)\n",
|
|||
|
|
"q2 = monthly_client_flow[\"Flow_EUR\"].quantile(0.66)\n",
|
|||
|
|
"\n",
|
|||
|
|
"# 3) Catégorisation des clients\n",
|
|||
|
|
"def categorize(flow):\n",
|
|||
|
|
" if flow <= q1:\n",
|
|||
|
|
" return \"Petits flows\"\n",
|
|||
|
|
" elif flow <= q2:\n",
|
|||
|
|
" return \"Flows moyens\"\n",
|
|||
|
|
" else:\n",
|
|||
|
|
" return \"Grands flows\"\n",
|
|||
|
|
"\n",
|
|||
|
|
"monthly_client_flow[\"Flow_category\"] = monthly_client_flow[\"Flow_EUR\"].apply(categorize)\n",
|
|||
|
|
"\n",
|
|||
|
|
"# 4) Nombre de clients dans chaque catégorie par mois\n",
|
|||
|
|
"category_counts = (\n",
|
|||
|
|
" monthly_client_flow.groupby([\"YearMonth\", \"Flow_category\"])\n",
|
|||
|
|
" .size()\n",
|
|||
|
|
" .unstack(fill_value=0)\n",
|
|||
|
|
")\n",
|
|||
|
|
"\n",
|
|||
|
|
"category_counts.index = category_counts.index.astype(str)\n",
|
|||
|
|
"\n",
|
|||
|
|
"# 5) Plot\n",
|
|||
|
|
"category_counts.plot(kind=\"bar\", stacked=True, figsize=(14,6))\n",
|
|||
|
|
"plt.title(\"Répartition des clients par niveau de flux mensuel\")\n",
|
|||
|
|
"plt.xlabel(\"Mois\")\n",
|
|||
|
|
"plt.ylabel(\"Nombre de clients\")\n",
|
|||
|
|
"plt.xticks(rotation=90)\n",
|
|||
|
|
"plt.tight_layout()\n",
|
|||
|
|
"plt.show()\n"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": 17,
|
|||
|
|
"id": "2c5a83e0-1faf-4745-88b3-c0fb363317fc",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [
|
|||
|
|
{
|
|||
|
|
"name": "stdout",
|
|||
|
|
"output_type": "stream",
|
|||
|
|
"text": [
|
|||
|
|
"Répartition des comptes par catégorie :\n",
|
|||
|
|
"Grands flows : YearMonth\n",
|
|||
|
|
"2015-01 432\n",
|
|||
|
|
"2015-02 499\n",
|
|||
|
|
"2015-03 536\n",
|
|||
|
|
"2015-04 530\n",
|
|||
|
|
"2015-05 472\n",
|
|||
|
|
" ... \n",
|
|||
|
|
"2025-07 412\n",
|
|||
|
|
"2025-08 388\n",
|
|||
|
|
"2025-09 407\n",
|
|||
|
|
"2025-10 418\n",
|
|||
|
|
"2025-11 231\n",
|
|||
|
|
"Name: Grands flows, Length: 131, dtype: int64 comptes\n",
|
|||
|
|
"Petits flows : YearMonth\n",
|
|||
|
|
"2015-01 7429\n",
|
|||
|
|
"2015-02 7380\n",
|
|||
|
|
"2015-03 7390\n",
|
|||
|
|
"2015-04 7416\n",
|
|||
|
|
"2015-05 7493\n",
|
|||
|
|
" ... \n",
|
|||
|
|
"2025-07 3474\n",
|
|||
|
|
"2025-08 3507\n",
|
|||
|
|
"2025-09 3509\n",
|
|||
|
|
"2025-10 3529\n",
|
|||
|
|
"2025-11 174\n",
|
|||
|
|
"Name: Petits flows, Length: 131, dtype: int64 comptes\n"
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"source": [
|
|||
|
|
"print(\"Répartition des comptes par catégorie :\")\n",
|
|||
|
|
"for cat, count in category_counts.items():\n",
|
|||
|
|
" print(f\"{cat} : {count} comptes\")\n"
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"cell_type": "code",
|
|||
|
|
"execution_count": 18,
|
|||
|
|
"id": "943b359e-b1c0-435e-943b-94167f8c566f",
|
|||
|
|
"metadata": {},
|
|||
|
|
"outputs": [
|
|||
|
|
{
|
|||
|
|
"name": "stdout",
|
|||
|
|
"output_type": "stream",
|
|||
|
|
"text": [
|
|||
|
|
"Moyenne du nombre de comptes par catégorie (sur toute la période) :\n",
|
|||
|
|
"Grands flows : 334 comptes en moyenne par mois\n",
|
|||
|
|
"Petits flows : 6736 comptes en moyenne par mois\n"
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"source": [
|
|||
|
|
"# Nombre de comptes dans chaque catégorie par mois\n",
|
|||
|
|
"category_counts_by_month = (\n",
|
|||
|
|
" monthly_client_flow.groupby([\"YearMonth\", \"Flow_category\"])\n",
|
|||
|
|
" .size()\n",
|
|||
|
|
" .unstack(fill_value=0)\n",
|
|||
|
|
")\n",
|
|||
|
|
"\n",
|
|||
|
|
"# Moyenne sur tous les mois\n",
|
|||
|
|
"category_counts_mean = category_counts_by_month.mean()\n",
|
|||
|
|
"print(\"Moyenne du nombre de comptes par catégorie (sur toute la période) :\")\n",
|
|||
|
|
"for cat, mean_val in category_counts_mean.items():\n",
|
|||
|
|
" print(f\"{cat} : {mean_val:.0f} comptes en moyenne par mois\")\n"
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"metadata": {
|
|||
|
|
"kernelspec": {
|
|||
|
|
"display_name": "Python 3 (ipykernel)",
|
|||
|
|
"language": "python",
|
|||
|
|
"name": "python3"
|
|||
|
|
},
|
|||
|
|
"language_info": {
|
|||
|
|
"codemirror_mode": {
|
|||
|
|
"name": "ipython",
|
|||
|
|
"version": 3
|
|||
|
|
},
|
|||
|
|
"file_extension": ".py",
|
|||
|
|
"mimetype": "text/x-python",
|
|||
|
|
"name": "python",
|
|||
|
|
"nbconvert_exporter": "python",
|
|||
|
|
"pygments_lexer": "ipython3",
|
|||
|
|
"version": "3.13.11"
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"nbformat": 4,
|
|||
|
|
"nbformat_minor": 5
|
|||
|
|
}
|