{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "c93a55c8",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-03T10:13:26.569404Z",
     "start_time": "2025-07-03T10:13:04.404599Z"
    }
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import geopandas as gpd\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import sys\n",
    "import os\n",
    "import importlib\n",
    "\n",
    "sys.path.append(os.path.abspath(\"..\"))\n",
    "import misc\n",
    "importlib.reload(misc)\n",
    "from misc import load_csv_dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c0b00261",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      ">> Loading CSV dataset from names_featured.csv\n",
      ">> Detected fieldnames: ['name', 'sex', 'region', 'year', 'words', 'length', 'probable_native', 'probable_surname', 'identified_category', 'identified_name', 'identified_surname', 'annotated', 'province']\n",
      ">> Successfully loaded with UTF-8 encoding\n"
     ]
    }
   ],
   "source": [
    "df = pd.DataFrame(load_csv_dataset(\"names_featured.csv\"))\n",
    "shapefile_path = \"../dataset/osm_rdc_11provinces_210611/OSM_RDC_11provinces_210611.shp\"\n",
    "gdf = gpd.read_file(shapefile_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c5aee565",
   "metadata": {},
   "source": [
    "## Breakdown by major province"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "dac785a7-1a32-4a1b-b35d-d8b85df60589",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Harmonise province names in the GeoDataFrame\n",
    "df['province_clean'] = df['province'].str.upper().str.strip().str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8')\n",
    "gdf['province_upper'] = gdf['name'].str.upper().str.strip().str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8')\n",
    "counts = df.groupby('province_clean').size().reset_index(name='count')\n",
    "gdf_merged = gdf.merge(counts, left_on='province_upper', right_on='province_clean', how='left')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "c3f83d00-0606-44ea-a704-fc54d69263b4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      province_upper   count\n",
      "0           KINSHASA  899076\n",
      "1          BAS-CONGO  215194\n",
      "2           SUD-KIVU  278843\n",
      "3          NORD-KIVU  316590\n",
      "4            MANIEMA  103123\n",
      "5   KASAI-OCCIDENTAL  297689\n",
      "6     KASAI-ORIENTAL  349469\n",
      "7           EQUATEUR  285102\n",
      "8          ORIENTALE  258574\n",
      "9           BANDUNDU  648499\n",
      "10           KATANGA  475953\n"
     ]
    }
   ],
   "source": [
    "print(gdf_merged[['province_upper', 'count']])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e3cd7add-3a83-44bd-abd2-ef8830dfe6b0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 118588 characters]",
      "text/plain": [
       "<Figure size 1000x1000 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Distribution of data by former province\n",
    "fig, ax = plt.subplots(figsize=(10, 10))\n",
    "gdf_merged.plot(column='count', cmap='Blues', edgecolor='black', legend=True, ax=ax)\n",
    "for idx, row in gdf_merged.iterrows():\n",
    "    if pd.notna(row['count']):\n",
    "        centroid = row['geometry'].centroid\n",
    "        plt.text(centroid.x, centroid.y, row['province_upper'], \n",
    "                 horizontalalignment='center', fontsize=8, color='black')\n",
    "\n",
    "plt.title('Distribution of data by former province')\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "27f6bcd2-f1de-419a-8d56-e29064934e2f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 81148 characters]",
      "text/plain": [
       "<Figure size 700x700 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "provinces = df['province'].value_counts()\n",
    "plt.figure(figsize=(7, 7))\n",
    "plt.pie(provinces, labels=provinces.index, autopct='%1.1f%%', startangle=140)\n",
    "plt.axis('equal')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "d51f3bee-d2a1-46a0-9e0b-af10c1ca7cb4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 47156 characters]",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10, 5))\n",
    "provinces.plot(kind='bar', color='skyblue')\n",
    "plt.xlabel(\"Province\")\n",
    "plt.ylabel(\"Persons\")\n",
    "plt.xticks(rotation=45)\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "0374f8ee",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-03T10:13:53.107207Z",
     "start_time": "2025-07-03T10:13:30.265456Z"
    }
   },
   "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>name</th>\n",
       "      <th>surname</th>\n",
       "      <th>middle_name</th>\n",
       "      <th>first_name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>epenge djongesongo jonas</td>\n",
       "      <td>epenge</td>\n",
       "      <td>djongesongo</td>\n",
       "      <td>jonas</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>eyongoyongo shako michel</td>\n",
       "      <td>eyongoyongo</td>\n",
       "      <td>shako</td>\n",
       "      <td>michel</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>okawonga ongondjo alphonse</td>\n",
       "      <td>okawonga</td>\n",
       "      <td>ongondjo</td>\n",
       "      <td>alphonse</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>ombala lokolo nathals</td>\n",
       "      <td>ombala</td>\n",
       "      <td>lokolo</td>\n",
       "      <td>nathals</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>shongo matete albert</td>\n",
       "      <td>shongo</td>\n",
       "      <td>matete</td>\n",
       "      <td>albert</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         name      surname  middle_name first_name\n",
       "0    epenge djongesongo jonas       epenge  djongesongo      jonas\n",
       "1    eyongoyongo shako michel  eyongoyongo        shako     michel\n",
       "2  okawonga ongondjo alphonse     okawonga     ongondjo   alphonse\n",
       "3       ombala lokolo nathals       ombala       lokolo    nathals\n",
       "4        shongo matete albert       shongo       matete     albert"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#breakdown of names into surname, middle name and first name\n",
    "#retrieve all rows whose name is identified as simple, and delete rows whose identified_name is null or empty\n",
    "\n",
    "df_simple = df[df['identified_category'] == 'simple'].copy()\n",
    "df_simple['surname'] = df_simple['identified_name'].str.split().str[0]\n",
    "df_simple['middle_name'] = df_simple['identified_name'].str.split().str[1]\n",
    "df_simple['first_name'] = df_simple['identified_surname']\n",
    "df_simple = df_simple[df_simple['first_name'].notna() & (df_simple['first_name'].str.strip() != '')]\n",
    "\n",
    "df_simple[['name', 'surname', 'middle_name', 'first_name']].head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f2924f79",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-03T10:14:06.060688Z",
     "start_time": "2025-07-03T10:13:57.540461Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 30016 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Simple distribution of first names (display of the 10 most popular first names)\n",
    "sns.countplot(y=df_simple['first_name'], order=df_simple['first_name'].value_counts().iloc[:10].index)\n",
    "plt.title(\"Top 10 first names (simple names only)\")\n",
    "plt.xlabel(\"Count\")\n",
    "plt.ylabel(\"First name\")\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "76979895",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-03T10:14:13.209239Z",
     "start_time": "2025-07-03T10:14:12.462839Z"
    }
   },
   "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>First name</th>\n",
       "      <th>quantity</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>jean</td>\n",
       "      <td>62143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>joseph</td>\n",
       "      <td>26678</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>esther</td>\n",
       "      <td>24639</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>marie</td>\n",
       "      <td>23330</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>grace</td>\n",
       "      <td>20964</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>david</td>\n",
       "      <td>20909</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>dorcas</td>\n",
       "      <td>20840</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>ruth</td>\n",
       "      <td>20633</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>patrick</td>\n",
       "      <td>20209</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>sarah</td>\n",
       "      <td>20190</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  First name  quantity\n",
       "0       jean     62143\n",
       "1     joseph     26678\n",
       "2     esther     24639\n",
       "3      marie     23330\n",
       "4      grace     20964\n",
       "5      david     20909\n",
       "6     dorcas     20840\n",
       "7       ruth     20633\n",
       "8    patrick     20209\n",
       "9      sarah     20190"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "firstnames = df_simple['first_name'].value_counts()\n",
    "df_firstnames = firstnames.reset_index()\n",
    "df_firstnames.columns = ['First name', 'quantity']\n",
    "df_firstnames.head(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "61e35f38-96da-4d04-9779-9b3409adeae6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 130044 characters]",
      "text/plain": [
       "<Figure size 1200x1200 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#Most common first name by province\n",
    "top_names = df_simple.groupby(['province_clean', 'first_name']).size().reset_index(name='count')\n",
    "top_names = top_names.sort_values(['province_clean', 'count'], ascending=[True, False])\n",
    "top_names = top_names.drop_duplicates(subset='province_clean', keep='first')\n",
    "gdf_named = gdf_merged.merge(top_names[['province_clean', 'first_name']], \n",
    "                             left_on='province_upper', right_on='province_clean', \n",
    "                             how='left')\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(12, 12))\n",
    "gdf_named.plot(column='count', cmap='Blues', edgecolor='black', legend=True, ax=ax)\n",
    "\n",
    "for idx, row in gdf_named.iterrows():\n",
    "    if pd.notna(row['first_name']):\n",
    "        centroid = row['geometry'].centroid\n",
    "        label = f\"{row['first_name']}\"\n",
    "        plt.text(centroid.x, centroid.y, label, \n",
    "                 horizontalalignment='center', fontsize=8, color='black')\n",
    "\n",
    "plt.title(\"Most common first name by province\")\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "5022f136-3174-406d-acf0-dee379969213",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-03T10:14:20.920229Z",
     "start_time": "2025-07-03T10:14:18.776729Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ">> Total number of first names registered : 3392438\n",
      ">> Number of all-male first names : 110947\n",
      ">> Number of all-female first names : 61318\n",
      ">> Number of all-neutral first names : 26593\n"
     ]
    }
   ],
   "source": [
    "# Total number of distinct first names\n",
    "total_firstnames = df_simple['first_name'].notna().sum()\n",
    "print(f\">> Total number of first names registered : {total_firstnames}\")\n",
    "\n",
    "# categorization of first names\n",
    "firstnames_by_sex = df_simple.groupby(['first_name', 'sex']).size().unstack(fill_value=0)\n",
    "male_firstnames = firstnames_by_sex[(firstnames_by_sex['m'] > 0) & (firstnames_by_sex['f'] == 0)]\n",
    "print(f\">> Number of all-male first names : {len(male_firstnames)}\")\n",
    "female_firstnames = firstnames_by_sex[(firstnames_by_sex['f'] > 0) & (firstnames_by_sex['m'] == 0)]\n",
    "print(f\">> Number of all-female first names : {len(female_firstnames)}\")\n",
    "neutral_firstnames = firstnames_by_sex[(firstnames_by_sex['m'] > 0) & (firstnames_by_sex['f'] > 0)]\n",
    "print(f\">> Number of all-neutral first names : {len(neutral_firstnames)}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "cfeec858-ad7e-4173-9262-a7d6e08a31d9",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-03T10:14:25.256143Z",
     "start_time": "2025-07-03T10:14:25.149415Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 34036 characters]",
      "text/plain": [
       "<Figure size 600x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# data for graphic interpretation \n",
    "labels = ['Male', 'Female', 'Neutral']\n",
    "values = [len(male_firstnames), len(female_firstnames), len(neutral_firstnames)]\n",
    "\n",
    "# circular\n",
    "plt.figure(figsize=(6,6))\n",
    "plt.pie(values, labels=labels, autopct='%1.1f%%', startangle=140, colors=['skyblue', 'lightgreen', 'lightgray'])\n",
    "plt.title(\"Distribution of first names by sex\")\n",
    "plt.axis('equal')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "cc1489c8-904f-4116-9872-8ba79f72eb94",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 92884 characters]",
      "text/plain": [
       "<Figure size 1000x800 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Assign first name sex category\n",
    "df_simple['first_name_sex_category'] = df_simple['first_name'].map(\n",
    "    lambda x: 'Male' if x in male_firstnames else (\n",
    "        'Female' if x in female_firstnames else (\n",
    "            'Neutral' if x in neutral_firstnames else None\n",
    "        )\n",
    "    )\n",
    ")\n",
    "\n",
    "df_cat = df_simple.dropna(subset=['first_name_sex_category'])\n",
    "category_counts = df_cat.groupby(['province_clean', 'first_name_sex_category']).size().unstack(fill_value=0)\n",
    "category_counts['dominant_category'] = category_counts.idxmax(axis=1)\n",
    "map_df = gdf.set_index('province_upper').join(category_counts['dominant_category'])\n",
    "\n",
    "color_map = {'Male': 'skyblue', 'Female': 'lightgreen', 'Neutral': 'lightgray'}\n",
    "map_df['color'] = map_df['dominant_category'].map(color_map)\n",
    "\n",
    "fig, ax = plt.subplots(1, 1, figsize=(10, 8))\n",
    "map_df.plot(color=map_df['color'], edgecolor='black', ax=ax)\n",
    "for idx, row in map_df.iterrows():\n",
    "    plt.annotate(text=row['dominant_category'], xy=(row.geometry.centroid.x, row.geometry.centroid.y),\n",
    "                 horizontalalignment='center', fontsize=8, color='black')\n",
    "\n",
    "plt.title(\"Dominant first name category by province\")\n",
    "plt.axis('off')\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "f94818e6-7c91-4f33-8070-0ec2cb8c0063",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 24672 characters]",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Histogram\n",
    "plt.figure(figsize=(6,4))\n",
    "plt.bar(labels, values, color=['skyblue', 'lightpink', 'lightgray'])\n",
    "plt.title(\"Distribution of first names by sex\")\n",
    "plt.ylabel(\"Number of first names\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "66e7aa9c-34ee-4a3b-aa6e-806eee980df4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ">> Number of distinct regions: 12\n",
      "Number of unique first names per region\n"
     ]
    },
    {
     "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>Region</th>\n",
       "      <th>Unique first names</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>kinshasa</td>\n",
       "      <td>75509</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>bandundu</td>\n",
       "      <td>43309</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>katanga</td>\n",
       "      <td>37932</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>autres</td>\n",
       "      <td>31487</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>nord-kivu</td>\n",
       "      <td>27300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>equateur</td>\n",
       "      <td>25389</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>bas-congo</td>\n",
       "      <td>24154</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>sud-kivu</td>\n",
       "      <td>23834</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>orientale</td>\n",
       "      <td>18356</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>kasaï-oriental</td>\n",
       "      <td>15906</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>kasaï-occidental</td>\n",
       "      <td>12365</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>maniema</td>\n",
       "      <td>11949</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              Region  Unique first names\n",
       "0           kinshasa               75509\n",
       "1           bandundu               43309\n",
       "2            katanga               37932\n",
       "3             autres               31487\n",
       "4          nord-kivu               27300\n",
       "5           equateur               25389\n",
       "6          bas-congo               24154\n",
       "7           sud-kivu               23834\n",
       "8          orientale               18356\n",
       "9     kasaï-oriental               15906\n",
       "10  kasaï-occidental               12365\n",
       "11           maniema               11949"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Count of unique first names per region (province)\n",
    "distinct_regions = df_simple['province'].nunique()\n",
    "print(f\">> Number of distinct regions: {distinct_regions}\")\n",
    "firstnames_by_region = df_simple.groupby('province')['first_name'].nunique().sort_values(ascending=False)\n",
    "\n",
    "print(\"Number of unique first names per region\")\n",
    "df_firstnames_region = firstnames_by_region.reset_index()\n",
    "df_firstnames_region.columns = ['Region', 'Unique first names']\n",
    "df_firstnames_region.head(12)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "26d227c3-b32a-4cf9-843f-fb6959090a48",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 110752 characters]",
      "text/plain": [
       "<Figure size 1000x1000 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "unique_first_names = df_simple.groupby('province')['first_name'].nunique().reset_index(name='unique_count')\n",
    "unique_first_names['province_clean'] = unique_first_names['province'].str.upper().str.strip() \\\n",
    "    .str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8')\n",
    "gdf_diversity = gdf_merged.merge(unique_first_names[['province_clean', 'unique_count']], on='province_clean', how='left')\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(10, 10))\n",
    "gdf_diversity.plot(column='unique_count', cmap='viridis', edgecolor='black', legend=True, ax=ax)\n",
    "\n",
    "for idx, row in gdf_diversity.iterrows():\n",
    "    centroid = row['geometry'].centroid\n",
    "    plt.text(centroid.x, centroid.y, row['province_upper'], \n",
    "             horizontalalignment='center', fontsize=8, color='black')\n",
    "\n",
    "plt.title(\"First name diversity by province\")\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "b4a18bad-bd59-4909-81ac-705767675dd8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUTRES\n",
      "    jean            3626\n",
      "    patrick         2202\n",
      "    tresor          1965\n",
      "\n",
      "BANDUNDU\n",
      "    jean            4946\n",
      "    joel            1583\n",
      "    marie           1163\n",
      "\n",
      "BAS-CONGO\n",
      "    jean            3380\n",
      "    joseph          2090\n",
      "    marie           1803\n",
      "\n",
      "EQUATEUR\n",
      "    jean            8194\n",
      "    joseph          3095\n",
      "    marie           2318\n",
      "\n",
      "KASAÏ-OCCIDENTAL\n",
      "    jean            10390\n",
      "    andre           4787\n",
      "    marie           3589\n",
      "\n",
      "KASAÏ-ORIENTAL\n",
      "    jean            14205\n",
      "    joseph          5192\n",
      "    marie           4772\n",
      "\n",
      "KATANGA\n",
      "    jean            5300\n",
      "    ruth            3185\n",
      "    esther          3018\n",
      "\n",
      "KINSHASA\n",
      "    ruth            9823\n",
      "    dorcas          9801\n",
      "    sarah           9696\n",
      "\n",
      "MANIEMA\n",
      "    jean            1200\n",
      "    joseph          649\n",
      "    marie           528\n",
      "\n",
      "NORD-KIVU\n",
      "    justin          3301\n",
      "    grace           2991\n",
      "    moise           2790\n",
      "\n",
      "ORIENTALE\n",
      "    jean            4447\n",
      "    joseph          2755\n",
      "    moise           2566\n",
      "\n",
      "SUD-KIVU\n",
      "    justin          2244\n",
      "    christian       1835\n",
      "    jean            1762\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# top 3 most popular first names by region\n",
    "grouped = df_simple.groupby(['province', 'first_name']).size().reset_index(name='count')\n",
    "grouped = grouped.sort_values(['province', 'count'], ascending=[True, False])\n",
    "top3_by_region = grouped.groupby('province').head(3)\n",
    "\n",
    "for province, group in top3_by_region.groupby('province'):\n",
    "    print(f\"{province.upper()}\")\n",
    "    for _, row in group.iterrows():\n",
    "        print(f\"    {row['first_name']:<15} {row['count']}\")\n",
    "    print()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "18744cca-72f1-4830-affc-e64af824225a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUTRES - Neutral\n",
      "    m               26\n",
      "    f               4\n",
      "\n",
      "AUTRES - f\n",
      "    gracia          1257\n",
      "    marie           1031\n",
      "    sarah           892\n",
      "\n",
      "AUTRES - m\n",
      "    jean            3617\n",
      "    patrick         2189\n",
      "    tresor          1948\n",
      "\n",
      "BANDUNDU - Neutral\n",
      "    m               68\n",
      "    f               27\n",
      "\n",
      "BANDUNDU - f\n",
      "    marie           1126\n",
      "    ruth            1059\n",
      "    esther          1053\n",
      "\n",
      "BANDUNDU - m\n",
      "    jean            4917\n",
      "    joel            1539\n",
      "    dieu            1118\n",
      "\n",
      "BAS-CONGO - Neutral\n",
      "    f               3\n",
      "    m               2\n",
      "\n",
      "BAS-CONGO - f\n",
      "    marie           1790\n",
      "    dorcas          1377\n",
      "    esther          1166\n",
      "\n",
      "BAS-CONGO - m\n",
      "    jean            3369\n",
      "    joseph          2082\n",
      "    andre           1169\n",
      "\n",
      "EQUATEUR - Neutral\n",
      "    m               8\n",
      "    f               2\n",
      "\n",
      "EQUATEUR - f\n",
      "    marie           2277\n",
      "    esther          1807\n",
      "    ruth            1371\n",
      "\n",
      "EQUATEUR - m\n",
      "    jean            8161\n",
      "    joseph          3083\n",
      "    jeremie         2243\n",
      "\n",
      "KASAÏ-OCCIDENTAL - Neutral\n",
      "    m               17\n",
      "    f               9\n",
      "\n",
      "KASAÏ-OCCIDENTAL - f\n",
      "    marie           3517\n",
      "    therese         1594\n",
      "    esther          1456\n",
      "\n",
      "KASAÏ-OCCIDENTAL - m\n",
      "    jean            10374\n",
      "    andre           4782\n",
      "    francois        3332\n",
      "\n",
      "KASAÏ-ORIENTAL - Neutral\n",
      "    m               14\n",
      "    f               1\n",
      "\n",
      "KASAÏ-ORIENTAL - f\n",
      "    marie           4713\n",
      "    therese         2506\n",
      "    rachel          1599\n",
      "\n",
      "KASAÏ-ORIENTAL - m\n",
      "    jean            14179\n",
      "    joseph          5178\n",
      "    andre           4469\n",
      "\n",
      "KATANGA - Neutral\n",
      "    m               3\n",
      "\n",
      "KATANGA - f\n",
      "    ruth            3171\n",
      "    esther          3005\n",
      "    sarah           2889\n",
      "\n",
      "KATANGA - m\n",
      "    jean            5282\n",
      "    daniel          2679\n",
      "    gloire          2676\n",
      "\n",
      "KINSHASA - Neutral\n",
      "    m               26\n",
      "    f               5\n",
      "\n",
      "KINSHASA - f\n",
      "    ruth            9756\n",
      "    dorcas          9737\n",
      "    sarah           9626\n",
      "\n",
      "KINSHASA - m\n",
      "    jonathan        8574\n",
      "    christian       7770\n",
      "    exauce          5838\n",
      "\n",
      "MANIEMA - Neutral\n",
      "    f               3\n",
      "    m               2\n",
      "\n",
      "MANIEMA - f\n",
      "    marie           496\n",
      "    esther          217\n",
      "    jeanne          216\n",
      "\n",
      "MANIEMA - m\n",
      "    jean            1198\n",
      "    joseph          646\n",
      "    pierre          432\n",
      "\n",
      "NORD-KIVU - Neutral\n",
      "    m               15\n",
      "    f               4\n",
      "\n",
      "NORD-KIVU - f\n",
      "    esther          2681\n",
      "    rachel          2384\n",
      "    neema           1764\n",
      "\n",
      "NORD-KIVU - m\n",
      "    justin          3255\n",
      "    moise           2777\n",
      "    jean            2098\n",
      "\n",
      "ORIENTALE - Neutral\n",
      "    m               7\n",
      "    f               3\n",
      "\n",
      "ORIENTALE - f\n",
      "    esther          2383\n",
      "    marie           1963\n",
      "    sarah           1401\n",
      "\n",
      "ORIENTALE - m\n",
      "    jean            4430\n",
      "    joseph          2736\n",
      "    moise           2557\n",
      "\n",
      "SUD-KIVU - Neutral\n",
      "    m               25\n",
      "    f               9\n",
      "\n",
      "SUD-KIVU - f\n",
      "    esther          1174\n",
      "    francine        906\n",
      "    esperance       839\n",
      "\n",
      "SUD-KIVU - m\n",
      "    justin          2205\n",
      "    christian       1817\n",
      "    jean            1748\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#Group by region, gender and first name, then count\n",
    "def determine_sex_category(row):\n",
    "    if row['first_name'] in neutral_firstnames:\n",
    "        return 'Neutral'\n",
    "    return row['sex']\n",
    "\n",
    "df_simple['sex_category'] = df_simple.apply(determine_sex_category, axis=1)\n",
    "\n",
    "# Groupement\n",
    "grouped = df_simple.groupby(['province', 'sex_category', 'first_name']).size().reset_index(name='count')\n",
    "grouped = grouped.sort_values(['province', 'sex_category', 'count'], ascending=[True, True, False])\n",
    "top3_by_region_sex = grouped.groupby(['province', 'sex_category']).head(3)\n",
    "\n",
    "for (province, sex), group in top3_by_region_sex.groupby(['province', 'sex_category']):\n",
    "    print(f\"{province.upper()} - {sex}\")\n",
    "    for _, row in group.iterrows():\n",
    "        print(f\"    {row['first_name']:<15} {row['count']}\")\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "abbaa917-a6ba-45e7-b84d-d27bc104485b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Top 10 surnames for sex: f\n",
      "    kavira          18323\n",
      "    kavugho         10909\n",
      "    kahindo         10821\n",
      "    ntumba          9216\n",
      "    ilunga          8672\n",
      "    ngalula         8446\n",
      "    mbuyi           8437\n",
      "    masika          8290\n",
      "    mujinga         8017\n",
      "    kapinga         7920\n",
      "\n",
      "Top 10 surnames for sex: m\n",
      "    ilunga          24581\n",
      "    kambale         18604\n",
      "    ngoy            16610\n",
      "    kasongo         16420\n",
      "    kasereka        12842\n",
      "    muhindo         11467\n",
      "    kazadi          9761\n",
      "    mutombo         9262\n",
      "    kakule          9179\n",
      "    mumbere         8871\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Grouping surnames by sex\n",
    "surnames_by_sex = df_simple.groupby(['surname', 'sex']).size().reset_index(name='count')\n",
    "surnames_by_sex = surnames_by_sex.sort_values(['sex', 'count'], ascending=[True, False])\n",
    "top10_per_sex = surnames_by_sex.groupby('sex').head(10)\n",
    "\n",
    "for sex, group in top10_per_sex.groupby('sex'):\n",
    "    print(f\"Top 10 surnames for sex: {sex}\")\n",
    "    for _, row in group.iterrows():\n",
    "        print(f\"    {row['surname']:<15} {row['count']}\")\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "5823f6ff-b4bb-44df-803c-724bf244e885",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUTRES\n",
      "    ilunga          7135\n",
      "    ngoy            5776\n",
      "    kasongo         4363\n",
      "\n",
      "BANDUNDU\n",
      "    mbo             3479\n",
      "    mpia            2408\n",
      "    mputu           1777\n",
      "\n",
      "BAS-CONGO\n",
      "    nzuzi           3836\n",
      "    nlandu          3292\n",
      "    matondo         2796\n",
      "\n",
      "EQUATEUR\n",
      "    mboyo           1676\n",
      "    lokuli          902\n",
      "    bolumbu         816\n",
      "\n",
      "KASAÏ-OCCIDENTAL\n",
      "    ntumba          4999\n",
      "    mbuyi           4114\n",
      "    kanku           2805\n",
      "\n",
      "KASAÏ-ORIENTAL\n",
      "    ngoyi           7899\n",
      "    ilunga          5223\n",
      "    mbuyi           4719\n",
      "\n",
      "KATANGA\n",
      "    ilunga          15911\n",
      "    ngoy            13243\n",
      "    kasongo         9776\n",
      "\n",
      "KINSHASA\n",
      "    ntumba          4741\n",
      "    nsimba          4470\n",
      "    matondo         4382\n",
      "\n",
      "MANIEMA\n",
      "    amisi           964\n",
      "    ramazani        843\n",
      "    assani          596\n",
      "\n",
      "NORD-KIVU\n",
      "    kambale         17178\n",
      "    kavira          17001\n",
      "    kasereka        11931\n",
      "\n",
      "ORIENTALE\n",
      "    bahati          1059\n",
      "    baraka          867\n",
      "    kambale         849\n",
      "\n",
      "SUD-KIVU\n",
      "    bahati          2353\n",
      "    furaha          1964\n",
      "    mugisho         1876\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Grouping surnames by region\n",
    "surnames_by_region = df_simple.groupby(['province', 'surname']).size().reset_index(name='count')\n",
    "surnames_by_region = surnames_by_region.sort_values(['province', 'count'], ascending=[True, False])\n",
    "top3_surnames_per_region = surnames_by_region.groupby('province').head(3)\n",
    "\n",
    "for province, group in top3_surnames_per_region.groupby('province'):\n",
    "    print(f\"{province.upper()}\")\n",
    "    for _, row in group.iterrows():\n",
    "        print(f\"    {row['surname']:<15} {row['count']}\")\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "a15ba0c5-9a4f-4876-93ac-5f4a5a5d50ba",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUTRES - f\n",
      "    ilunga          1753\n",
      "    ngoy            982\n",
      "    ngoie           960\n",
      "\n",
      "AUTRES - m\n",
      "    ilunga          5382\n",
      "    ngoy            4794\n",
      "    kasongo         3406\n",
      "\n",
      "BANDUNDU - f\n",
      "    mbo             1207\n",
      "    mpia            875\n",
      "    mputu           658\n",
      "\n",
      "BANDUNDU - m\n",
      "    mbo             2272\n",
      "    mpia            1533\n",
      "    mputu           1119\n",
      "\n",
      "BAS-CONGO - f\n",
      "    nzuzi           2054\n",
      "    nlandu          1529\n",
      "    tsimba          1463\n",
      "\n",
      "BAS-CONGO - m\n",
      "    nzuzi           1782\n",
      "    nlandu          1763\n",
      "    ngoma           1669\n",
      "\n",
      "EQUATEUR - f\n",
      "    mboyo           796\n",
      "    bolumbu         633\n",
      "    amba            466\n",
      "\n",
      "EQUATEUR - m\n",
      "    mboyo           880\n",
      "    lokuli          715\n",
      "    lokwa           456\n",
      "\n",
      "KASAÏ-OCCIDENTAL - f\n",
      "    ngalula         2629\n",
      "    kapinga         1597\n",
      "    ntumba          1536\n",
      "\n",
      "KASAÏ-OCCIDENTAL - m\n",
      "    ntumba          3463\n",
      "    ngalamulume     2735\n",
      "    mbuyi           2666\n",
      "\n",
      "KASAÏ-ORIENTAL - f\n",
      "    ntumba          2074\n",
      "    mbuyi           2023\n",
      "    ngoyi           1705\n",
      "\n",
      "KASAÏ-ORIENTAL - m\n",
      "    ngoyi           6194\n",
      "    ilunga          4742\n",
      "    kazadi          3876\n",
      "\n",
      "KATANGA - f\n",
      "    ilunga          5360\n",
      "    ngoy            3603\n",
      "    kasongo         2886\n",
      "\n",
      "KATANGA - m\n",
      "    ilunga          10551\n",
      "    ngoy            9640\n",
      "    kasongo         6890\n",
      "\n",
      "KINSHASA - f\n",
      "    ntumba          3245\n",
      "    ngalula         2831\n",
      "    kapinga         2663\n",
      "\n",
      "KINSHASA - m\n",
      "    ilunga          2030\n",
      "    nsimba          1848\n",
      "    matondo         1832\n",
      "\n",
      "MANIEMA - f\n",
      "    fatuma          206\n",
      "    feza            185\n",
      "    mangaza         140\n",
      "\n",
      "MANIEMA - m\n",
      "    amisi           829\n",
      "    ramazani        719\n",
      "    assani          511\n",
      "\n",
      "NORD-KIVU - f\n",
      "    kavira          16945\n",
      "    kavugho         10351\n",
      "    kahindo         10016\n",
      "\n",
      "NORD-KIVU - m\n",
      "    kambale         17137\n",
      "    kasereka        11889\n",
      "    muhindo         10482\n",
      "\n",
      "ORIENTALE - f\n",
      "    kavira          817\n",
      "    mave            669\n",
      "    sifa            568\n",
      "\n",
      "ORIENTALE - m\n",
      "    bahati          851\n",
      "    kambale         840\n",
      "    baraka          836\n",
      "\n",
      "SUD-KIVU - f\n",
      "    furaha          1920\n",
      "    neema           1827\n",
      "    nabintu         1557\n",
      "\n",
      "SUD-KIVU - m\n",
      "    mugisho         1851\n",
      "    bahati          1757\n",
      "    murhula         1678\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Grouping surnames by region and sex\n",
    "grouped = df_simple.groupby(['province', 'sex', 'surname']).size().reset_index(name='count')\n",
    "grouped = grouped.sort_values(['province', 'sex', 'count'], ascending=[True, True, False])\n",
    "top3_surnames_by_region_sex = grouped.groupby(['province', 'sex']).head(3)\n",
    "\n",
    "for (province, sex), group in top3_surnames_by_region_sex.groupby(['province', 'sex']):\n",
    "    print(f\"{province.upper()} - {sex}\")\n",
    "    for _, row in group.iterrows():\n",
    "        print(f\"    {row['surname']:<15} {row['count']}\")\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "0c216ab9-6db0-4b15-82c0-a5f3f0dc641f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUTRES → ilunga (5382 M / 1753 F) - Total: 7135\n",
      "BANDUNDU → mbo (2272 M / 1207 F) - Total: 3479\n",
      "BAS-CONGO → nzuzi (1782 M / 2054 F) - Total: 3836\n",
      "EQUATEUR → mboyo (880 M / 796 F) - Total: 1676\n",
      "KASAÏ-OCCIDENTAL → ntumba (3463 M / 1536 F) - Total: 4999\n",
      "KASAÏ-ORIENTAL → ngoyi (6194 M / 1705 F) - Total: 7899\n",
      "KATANGA → ilunga (10551 M / 5360 F) - Total: 15911\n",
      "KINSHASA → ntumba (1496 M / 3245 F) - Total: 4741\n",
      "MANIEMA → amisi (829 M / 135 F) - Total: 964\n",
      "NORD-KIVU → kambale (17137 M / 41 F) - Total: 17178\n",
      "ORIENTALE → bahati (851 M / 208 F) - Total: 1059\n",
      "SUD-KIVU → bahati (1757 M / 596 F) - Total: 2353\n"
     ]
    }
   ],
   "source": [
    "# Find surnames common to both sexes per region - the most popular per region\n",
    "\n",
    "common_surnames = df_simple.groupby(['province', 'surname', 'sex']).size().unstack(fill_value=0)\n",
    "common_surnames = common_surnames[(common_surnames.get('m', 0) > 0) & (common_surnames.get('f', 0) > 0)]\n",
    "common_surnames['total'] = common_surnames['m'] + common_surnames['f']\n",
    "common_surnames = common_surnames.reset_index()\n",
    "top_common_surnames = common_surnames.sort_values(['province', 'total'], ascending=[True, False])\n",
    "top_common_surnames = top_common_surnames.groupby('province').first().reset_index()\n",
    "\n",
    "for _, row in top_common_surnames.iterrows():\n",
    "    print(f\"{row['province'].upper()} → {row['surname']} ({row['m']} M / {row['f']} F) - Total: {row['total']}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "497dd072-b4ee-4b2a-8887-db7543969855",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Top 10 middle names for sex: f\n",
      "    ilunga          8881\n",
      "    kasongo         6670\n",
      "    kazadi          5320\n",
      "    ngoy            5118\n",
      "    ntumba          4987\n",
      "    mutombo         4785\n",
      "    kabeya          3752\n",
      "    mukendi         3704\n",
      "    matondo         3666\n",
      "    ngoyi           3588\n",
      "\n",
      "Top 10 middle names for sex: m\n",
      "    ilunga          15062\n",
      "    kasongo         11344\n",
      "    ngoy            10703\n",
      "    mutombo         8881\n",
      "    kazadi          8790\n",
      "    ntumba          7446\n",
      "    ngoyi           7445\n",
      "    kabeya          6425\n",
      "    mukendi         6333\n",
      "    kalala          6214\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Grouping middle names by sex\n",
    "middlenames_by_sex = df_simple.groupby(['middle_name', 'sex']).size().reset_index(name='count')\n",
    "middlenames_by_sex = middlenames_by_sex.sort_values(['sex', 'count'], ascending=[True, False])\n",
    "top10_middlenames_per_sex = middlenames_by_sex.groupby('sex').head(10)\n",
    "\n",
    "for sex, group in top10_middlenames_per_sex.groupby('sex'):\n",
    "    print(f\"Top 10 middle names for sex: {sex}\")\n",
    "    for _, row in group.iterrows():\n",
    "        print(f\"    {row['middle_name']:<15} {row['count']}\")\n",
    "    print()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "78253678-8bcd-4c29-9412-b0b4a5d5268c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUTRES\n",
      "    ngoy                 3646\n",
      "    ilunga               3591\n",
      "    kasongo              2761\n",
      "\n",
      "BANDUNDU\n",
      "    moke                 3243\n",
      "    mbo                  1634\n",
      "    mpia                 1444\n",
      "\n",
      "BAS-CONGO\n",
      "    ngoma                3570\n",
      "    nlandu               2066\n",
      "    khonde               1787\n",
      "\n",
      "EQUATEUR\n",
      "    mboyo                1226\n",
      "    lokuli               1071\n",
      "    nkoy                 724\n",
      "\n",
      "KASAÏ-OCCIDENTAL\n",
      "    ntumba               4552\n",
      "    muamba               2830\n",
      "    ngalamulume          2329\n",
      "\n",
      "KASAÏ-ORIENTAL\n",
      "    ngoyi                8302\n",
      "    ilunga               6402\n",
      "    kazadi               5260\n",
      "\n",
      "KATANGA\n",
      "    ilunga               8185\n",
      "    ngoy                 8108\n",
      "    kasongo              6136\n",
      "\n",
      "KINSHASA\n",
      "    matondo              3989\n",
      "    ntumba               3289\n",
      "    ilunga               3232\n",
      "\n",
      "MANIEMA\n",
      "    ramazani             835\n",
      "    amisi                625\n",
      "    shabani              525\n",
      "\n",
      "NORD-KIVU\n",
      "    tsongo               1678\n",
      "    bahati               1212\n",
      "    mahamba              946\n",
      "\n",
      "ORIENTALE\n",
      "    ramazani             549\n",
      "    bahati               476\n",
      "    yenga                432\n",
      "\n",
      "SUD-KIVU\n",
      "    bisimwa              1658\n",
      "    bahati               1633\n",
      "    mirindi              1049\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Grouping middle names by region\n",
    "middlenames_by_region = df_simple.groupby(['province', 'middle_name']).size().reset_index(name='count')\n",
    "middlenames_by_region = middlenames_by_region.sort_values(['province', 'count'], ascending=[True, False])\n",
    "top3_middlenames_per_region = middlenames_by_region.groupby('province').head(3)\n",
    "\n",
    "for province, group in top3_middlenames_per_region.groupby('province'):\n",
    "    print(f\"{province.upper()}\")\n",
    "    for _, row in group.iterrows():\n",
    "        print(f\"    {row['middle_name']:<20} {row['count']}\")\n",
    "    print()    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "1e8697a3-edcb-4d15-a33f-0f3b8a8adcd0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUTRES - f\n",
      "    ilunga               1196\n",
      "    kasongo              917\n",
      "    ngoy                 824\n",
      "\n",
      "AUTRES - m\n",
      "    ngoy                 2822\n",
      "    ilunga               2395\n",
      "    kasongo              1844\n",
      "\n",
      "BANDUNDU - f\n",
      "    mbo                  669\n",
      "    mpia                 590\n",
      "    modiri               580\n",
      "\n",
      "BANDUNDU - m\n",
      "    moke                 2829\n",
      "    mbo                  965\n",
      "    n                    894\n",
      "\n",
      "BAS-CONGO - f\n",
      "    ngoma                1574\n",
      "    nlandu               920\n",
      "    khonde               797\n",
      "\n",
      "BAS-CONGO - m\n",
      "    ngoma                1996\n",
      "    nlandu               1146\n",
      "    muanda               999\n",
      "\n",
      "EQUATEUR - f\n",
      "    mboyo                462\n",
      "    lokuli               362\n",
      "    lokwa                219\n",
      "\n",
      "EQUATEUR - m\n",
      "    mboyo                764\n",
      "    lokuli               709\n",
      "    nkoy                 509\n",
      "\n",
      "KASAÏ-OCCIDENTAL - f\n",
      "    ntumba               1136\n",
      "    muamba               679\n",
      "    mulumba              597\n",
      "\n",
      "KASAÏ-OCCIDENTAL - m\n",
      "    ntumba               3416\n",
      "    muamba               2151\n",
      "    ngalamulume          1790\n",
      "\n",
      "KASAÏ-ORIENTAL - f\n",
      "    ngoyi                2488\n",
      "    ilunga               1817\n",
      "    kazadi               1522\n",
      "\n",
      "KASAÏ-ORIENTAL - m\n",
      "    ngoyi                5814\n",
      "    ilunga               4585\n",
      "    kazadi               3738\n",
      "\n",
      "KATANGA - f\n",
      "    ilunga               3504\n",
      "    ngoy                 2664\n",
      "    kasongo              2578\n",
      "\n",
      "KATANGA - m\n",
      "    ngoy                 5444\n",
      "    ilunga               4681\n",
      "    kasongo              3558\n",
      "\n",
      "KINSHASA - f\n",
      "    matondo              2325\n",
      "    ntumba               1947\n",
      "    ilunga               1606\n",
      "\n",
      "KINSHASA - m\n",
      "    matondo              1664\n",
      "    ilunga               1626\n",
      "    kasongo              1539\n",
      "\n",
      "MANIEMA - f\n",
      "    fatuma               162\n",
      "    feza                 153\n",
      "    sifa                 123\n",
      "\n",
      "MANIEMA - m\n",
      "    ramazani             713\n",
      "    amisi                523\n",
      "    shabani              421\n",
      "\n",
      "NORD-KIVU - f\n",
      "    tsongo               739\n",
      "    furaha               525\n",
      "    bahati               522\n",
      "\n",
      "NORD-KIVU - m\n",
      "    tsongo               939\n",
      "    bahati               690\n",
      "    muhindo              578\n",
      "\n",
      "ORIENTALE - f\n",
      "    mave                 406\n",
      "    neema                320\n",
      "    furaha               265\n",
      "\n",
      "ORIENTALE - m\n",
      "    ramazani             409\n",
      "    baraka               300\n",
      "    kombozi              290\n",
      "\n",
      "SUD-KIVU - f\n",
      "    bisimwa              726\n",
      "    bahati               717\n",
      "    mirindi              456\n",
      "\n",
      "SUD-KIVU - m\n",
      "    bisimwa              932\n",
      "    bahati               916\n",
      "    mirindi              593\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Grouping middle names by province and sex\n",
    "middlenames_by_province_sex = df_simple.groupby(['province', 'sex', 'middle_name']).size().reset_index(name='count')\n",
    "middlenames_by_province_sex = middlenames_by_province_sex.sort_values(['province', 'sex', 'count'], ascending=[True, True, False])\n",
    "top3_middlenames_by_province_sex = middlenames_by_province_sex.groupby(['province', 'sex']).head(3)\n",
    "\n",
    "for (province, sex), group in top3_middlenames_by_province_sex.groupby(['province', 'sex']):\n",
    "    print(f\"{province.upper()} - {sex}\")\n",
    "    for _, row in group.iterrows():\n",
    "        print(f\"    {row['middle_name']:<20} {row['count']}\")\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "38a99578-e224-472b-95ac-e2f2510f8347",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUTRES\n",
      "    ngoy                 3646\n",
      "    ilunga               3591\n",
      "    kasongo              2761\n",
      "\n",
      "BANDUNDU\n",
      "    moke                 3243\n",
      "    mbo                  1634\n",
      "    mpia                 1444\n",
      "\n",
      "BAS-CONGO\n",
      "    ngoma                3570\n",
      "    nlandu               2066\n",
      "    khonde               1787\n",
      "\n",
      "EQUATEUR\n",
      "    mboyo                1226\n",
      "    lokuli               1071\n",
      "    nkoy                 724\n",
      "\n",
      "KASAÏ-OCCIDENTAL\n",
      "    ntumba               4552\n",
      "    muamba               2830\n",
      "    ngalamulume          2329\n",
      "\n",
      "KASAÏ-ORIENTAL\n",
      "    ngoyi                8302\n",
      "    ilunga               6402\n",
      "    kazadi               5260\n",
      "\n",
      "KATANGA\n",
      "    ilunga               8185\n",
      "    ngoy                 8108\n",
      "    kasongo              6136\n",
      "\n",
      "KINSHASA\n",
      "    matondo              3989\n",
      "    ntumba               3289\n",
      "    ilunga               3232\n",
      "\n",
      "MANIEMA\n",
      "    ramazani             835\n",
      "    amisi                625\n",
      "    shabani              525\n",
      "\n",
      "NORD-KIVU\n",
      "    tsongo               1678\n",
      "    bahati               1212\n",
      "    mahamba              946\n",
      "\n",
      "ORIENTALE\n",
      "    ramazani             549\n",
      "    bahati               476\n",
      "    yenga                432\n",
      "\n",
      "SUD-KIVU\n",
      "    bisimwa              1658\n",
      "    bahati               1633\n",
      "    mirindi              1049\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Find middle names common to both sexes per region\n",
    "common_middlenames = df_simple.groupby(['province', 'middle_name', 'sex']).size().unstack(fill_value=0)\n",
    "common_middlenames = common_middlenames[(common_middlenames.get('m', 0) > 0) & (common_middlenames.get('f', 0) > 0)]\n",
    "common_middlenames['total'] = common_middlenames['m'] + common_middlenames['f']\n",
    "common_middlenames = common_middlenames.reset_index()\n",
    "common_middlenames = common_middlenames.sort_values(['province', 'total'], ascending=[True, False])\n",
    "top3_common_middlenames = common_middlenames.groupby('province').head(3)\n",
    "\n",
    "for province, group in top3_common_middlenames.groupby('province'):\n",
    "    print(f\"{province.upper()}\")\n",
    "    for _, row in group.iterrows():\n",
    "        print(f\"    {row['middle_name']:<20} {row['total']}\")\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "bdd0845d-c1e5-45db-97cb-6070190ba177",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 24932 characters]",
      "text/plain": [
       "<Figure size 600x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Pie chart of surnames by sex\n",
    "surnames_sex_count = surnames_by_sex.groupby('sex')['count'].sum()\n",
    "plt.figure(figsize=(6,6))\n",
    "plt.pie(surnames_sex_count, labels=surnames_sex_count.index, autopct='%1.1f%%', colors=['skyblue', 'lightpink'])\n",
    "plt.title(\"Distribution of Surnames by Sex\")\n",
    "plt.axis('equal')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "154b6421-a719-4574-8fcd-50bd8acd0d5c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 243756 characters]",
      "text/plain": [
       "<Figure size 1500x2000 with 12 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Pie chart of surnames by sex and region\n",
    "prov_sex_counts = df_simple.groupby(['province', 'sex']).size().reset_index(name='count')\n",
    "provinces = prov_sex_counts['province'].unique()\n",
    "cols = 3\n",
    "rows = (len(provinces) + cols - 1) // cols\n",
    "\n",
    "plt.figure(figsize=(cols * 5, rows * 5))\n",
    "for i, prov in enumerate(provinces, 1):\n",
    "    data = prov_sex_counts[prov_sex_counts['province'] == prov]\n",
    "    plt.subplot(rows, cols, i)\n",
    "    plt.pie(data['count'], labels=data['sex'], autopct='%1.1f%%', colors=['lightpink', 'skyblue'])\n",
    "    plt.title(f\"Distribution of Surnames by Sex\\nin {prov}\")\n",
    "    plt.axis('equal')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "b8ffcff1-7457-4a97-a1b0-629121a157f5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 53008 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# surnames per region (aggregated)\n",
    "top_surnames_region = surnames_by_region.sort_values('count', ascending=False).drop_duplicates('province').head(12)\n",
    "plt.figure(figsize=(10,6))\n",
    "sns.barplot(y='province', x='count', data=top_surnames_region, hue='surname', dodge=False)\n",
    "plt.title(\"Most Common Surname per Region\")\n",
    "plt.xlabel(\"Count\")\n",
    "plt.ylabel(\"Region\")\n",
    "plt.legend(title=\"Surname\", bbox_to_anchor=(1.05, 1), loc='upper left')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "13e9e7a6-40d4-4c72-b12c-e39a81b80617",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 131108 characters]",
      "text/plain": [
       "<Figure size 1200x1200 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Map of the most common surname by province in DRC\n",
    "top_surnames = df_simple.groupby(['province', 'surname']).size().reset_index(name='count')\n",
    "top_surnames = top_surnames.sort_values(['province', 'count'], ascending=[True, False])\n",
    "top_surnames = top_surnames.drop_duplicates(subset='province', keep='first')\n",
    "top_surnames['province_clean'] = top_surnames['province'].str.upper().str.strip() \\\n",
    "    .str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8')\n",
    "\n",
    "gdf_named = gdf_merged.merge(top_surnames[['province_clean', 'surname']], \n",
    "                             on='province_clean', how='left')\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(12, 12))\n",
    "gdf_named.plot(column='count', cmap='PuBu', edgecolor='black', legend=True, ax=ax)\n",
    "\n",
    "for idx, row in gdf_named.iterrows():\n",
    "    if pd.notna(row['surname']):\n",
    "        centroid = row['geometry'].centroid\n",
    "        plt.text(centroid.x, centroid.y, row['surname'], \n",
    "                 horizontalalignment='center', fontsize=8, color='black')\n",
    "\n",
    "plt.title(\"Most common surname by province\")\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "af71df02-7694-4da4-b60d-02bf73a20b71",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 46816 characters]",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Bar chart surnames by region and sex\n",
    "top10_regions = df_simple['province'].value_counts().head(12).index.tolist()\n",
    "df_top10 = df_simple[df_simple['province'].isin(top10_regions)]\n",
    "plt.figure(figsize=(12,6))\n",
    "sns.countplot(data=df_top10, y='province', hue='sex', order=top10_regions)\n",
    "plt.title(\"Surnames Distribution by Region and Sex\")\n",
    "plt.xlabel(\"Number of entries\")\n",
    "plt.ylabel(\"Region\")\n",
    "plt.legend(title='Sex')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "df7a7ce3-37c8-4ec5-9c03-6bd0f1c0a91b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 26392 characters]",
      "text/plain": [
       "<Figure size 600x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Pie chart of middle names by sex\n",
    "middlenames_sex_count = middlenames_by_province_sex.groupby('sex')['count'].sum()\n",
    "plt.figure(figsize=(6,6))\n",
    "plt.pie(middlenames_sex_count, labels=middlenames_sex_count.index, autopct='%1.1f%%', colors=['lightpink', 'skyblue'])\n",
    "plt.title(\"Distribution of Middle Names by Sex\")\n",
    "plt.axis('equal')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "7f713203-b498-4147-8a86-921f32dc5358",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 57516 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# most popular middle name per region\n",
    "top_middlename_region = middlenames_by_region.sort_values('count', ascending=False).drop_duplicates('province').head(12)\n",
    "plt.figure(figsize=(10,6))\n",
    "sns.barplot(y='province', x='count', data=top_middlename_region, hue='middle_name', dodge=False)\n",
    "plt.title(\"Most Common Middle Name per Region\")\n",
    "plt.xlabel(\"Count\")\n",
    "plt.ylabel(\"Region\")\n",
    "plt.legend(title=\"Middle Name\", bbox_to_anchor=(1.05, 1), loc='upper left')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "141b6d40-7397-4ce0-a104-cc06404c17bf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 132828 characters]",
      "text/plain": [
       "<Figure size 1200x1200 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Map of the most common middle by province in DRC\n",
    "top_surnames = df_simple.groupby(['province', 'middle_name']).size().reset_index(name='count')\n",
    "top_surnames = top_surnames.sort_values(['province', 'count'], ascending=[True, False])\n",
    "top_surnames = top_surnames.drop_duplicates(subset='province', keep='first')\n",
    "top_surnames['province_clean'] = top_surnames['province'].str.upper().str.strip() \\\n",
    "    .str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8')\n",
    "\n",
    "gdf_named = gdf_merged.merge(top_surnames[['province_clean', 'middle_name']], \n",
    "                             on='province_clean', how='left')\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(12, 12))\n",
    "gdf_named.plot(column='count', cmap='PuBu', edgecolor='black', legend=True, ax=ax)\n",
    "\n",
    "for idx, row in gdf_named.iterrows():\n",
    "    if pd.notna(row['middle_name']):\n",
    "        centroid = row['geometry'].centroid\n",
    "        plt.text(centroid.x, centroid.y, row['middle_name'], \n",
    "                 horizontalalignment='center', fontsize=8, color='black')\n",
    "\n",
    "plt.title(\"Most common middle name by province\")\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "a2124712-e13b-403c-96ec-e6d6f1fc15a7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 62532 characters]",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#Bar chart middle name by region and sex\n",
    "middlenames_by_sex_region = df_simple.groupby(['province', 'sex', 'middle_name']).size().reset_index(name='count')\n",
    "top_middlename_sex_region = middlenames_by_sex_region.sort_values('count', ascending=False).drop_duplicates(['province', 'sex'])\n",
    "\n",
    "# Bar chart\n",
    "plt.figure(figsize=(12, 6))\n",
    "sns.barplot(\n",
    "    data=top_middlename_sex_region,\n",
    "    x='province',\n",
    "    y='count',\n",
    "    hue='sex'\n",
    ")\n",
    "plt.title(\"Most Common Middle Name Count by Region and Sex\")\n",
    "plt.xlabel(\"Region\")\n",
    "plt.ylabel(\"Count\")\n",
    "plt.xticks(rotation=45)\n",
    "plt.legend(title=\"Sex\")\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "554a486f-6159-44af-a364-3dfb02dab33f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- Top 10 Firstname vs Surname Crossovers ---\n",
      "first_name  surname\n",
      "jean        ilunga     708\n",
      "            ngoyi      521\n",
      "            kasongo    514\n",
      "rachel      kavira     430\n",
      "jean        mbuyi      424\n",
      "justin      kambale    396\n",
      "jean        ntumba     393\n",
      "            ngoy       391\n",
      "neema       kavira     382\n",
      "esther      kavira     382\n",
      "dtype: int64\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Crossover 1: Firstname vs Surname\n",
    "crossover_firstname_surname = df_simple.groupby(['first_name', 'surname']).size().sort_values(ascending=False).head(10)\n",
    "print(\"--- Top 10 Firstname vs Surname Crossovers ---\")\n",
    "print(crossover_firstname_surname)\n",
    "print(\"\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "b850b301-6073-45f2-a015-e76d915a138f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- Top 10 Firstname vs Surname Crossovers by Sex ---\n",
      "\n",
      "SEX: f\n",
      "  rachel kavira — 428\n",
      "  neema kavira — 382\n",
      "  esther kavira — 381\n",
      "\n",
      "SEX: m\n",
      "  jean ilunga — 707\n",
      "  jean ngoyi — 521\n",
      "  jean kasongo — 513\n",
      "  jean mbuyi — 424\n",
      "  justin kambale — 396\n",
      "  jean ntumba — 393\n",
      "  jean ngoy — 388\n"
     ]
    }
   ],
   "source": [
    "# Crossover: Firstname vs Surname vs Sex\n",
    "crossover_fname_sname_sex = df_simple.groupby(['sex', 'first_name', 'surname']).size().reset_index(name='count')\n",
    "crossover_fname_sname_sex = crossover_fname_sname_sex.sort_values('count', ascending=False).head(10)\n",
    "\n",
    "print(\"--- Top 10 Firstname vs Surname Crossovers by Sex ---\")\n",
    "for sex, group in crossover_fname_sname_sex.groupby('sex'):\n",
    "    print(f\"\\nSEX: {sex}\")\n",
    "    for _, row in group.iterrows():\n",
    "        print(f\"  {row['first_name']} {row['surname']} — {row['count']}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "ffb67b85-4877-450e-9585-dd0d5fe6a0f3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 112764 characters]",
      "text/plain": [
       "<Figure size 1200x1000 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# frequency of joint appearance\n",
    "top_firstnames = df_simple['first_name'].value_counts().head(10).index\n",
    "top_surnames = df_simple['surname'].value_counts().head(10).index\n",
    "\n",
    "filtered_df = df_simple[\n",
    "    df_simple['first_name'].isin(top_firstnames) &\n",
    "    df_simple['surname'].isin(top_surnames)\n",
    "]\n",
    "\n",
    "cooccurrence = filtered_df.groupby(['first_name', 'surname']).size().unstack(fill_value=0)\n",
    "\n",
    "#heatmap\n",
    "plt.figure(figsize=(12, 10))\n",
    "sns.heatmap(cooccurrence, annot=True, fmt='d', cmap='Blues')\n",
    "plt.title('Heatmap of First Name vs Surname Cooccurrence')\n",
    "plt.xlabel('Surname')\n",
    "plt.ylabel('First Name')\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "6b9549ca-4c4e-4e9a-b1fd-2c49d96bdd2a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- Top 10 Firstname vs Middle Name Crossovers ---\n",
      "first_name  middle_name\n",
      "jean        ilunga         493\n",
      "            ngoyi          474\n",
      "kasongo     wa             459\n",
      "ilunga      wa             449\n",
      "jean        kasongo        397\n",
      "ngoy        ngoy           365\n",
      "jean        ntumba         361\n",
      "pierre      jean           341\n",
      "paul        jean           329\n",
      "ngoy        wa             322\n",
      "dtype: int64\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Crossover 2: Firstname vs Middle Name\n",
    "crossover_firstname_middlename = df_simple.groupby(['first_name', 'middle_name']).size().sort_values(ascending=False).head(10)\n",
    "print(\"--- Top 10 Firstname vs Middle Name Crossovers ---\")\n",
    "print(crossover_firstname_middlename)\n",
    "print(\"\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "f3bd5598-4f9e-4c95-a725-a1fd65f363b6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 115488 characters]",
      "text/plain": [
       "<Figure size 1200x1000 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# frequency of joint appearance\n",
    "top_middlenames = df_simple['middle_name'].value_counts().head(10).index\n",
    "\n",
    "filtered_df = df_simple[\n",
    "    df_simple['first_name'].isin(top_firstnames) &\n",
    "    df_simple['middle_name'].isin(top_middlenames)\n",
    "]\n",
    "\n",
    "cooccurrence = filtered_df.groupby(['first_name', 'middle_name']).size().unstack(fill_value=0)\n",
    "\n",
    "plt.figure(figsize=(12, 10))\n",
    "sns.heatmap(cooccurrence, annot=True, fmt='d', cmap='Greens')\n",
    "plt.title('Heatmap of First Name vs Middle Name Cooccurrence')\n",
    "plt.xlabel('Middle Name')\n",
    "plt.ylabel('First Name')\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "392da663-488c-4844-99ae-0f995d323824",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- Top 10 Firstname vs Middle Name Crossovers by Sex ---\n",
      "\n",
      "SEX: m\n",
      "  jean ilunga — 491\n",
      "  jean ngoyi — 474\n",
      "  jean kasongo — 396\n",
      "  jean ntumba — 357\n",
      "  pierre jean — 337\n",
      "  kasongo wa — 337\n",
      "  paul jean — 328\n",
      "  jean mutombo — 321\n",
      "  jean kazadi — 312\n",
      "  ilunga wa — 295\n"
     ]
    }
   ],
   "source": [
    "# Crossover: Firstname vs Middle Name vs Sex\n",
    "crossover_fname_middlename_sex = df_simple.groupby(['sex', 'first_name', 'middle_name']).size().reset_index(name='count')\n",
    "crossover_fname_middlename_sex = crossover_fname_middlename_sex.sort_values('count', ascending=False).head(10)\n",
    "\n",
    "print(\"--- Top 10 Firstname vs Middle Name Crossovers by Sex ---\")\n",
    "for sex, group in crossover_fname_middlename_sex.groupby('sex'):\n",
    "    print(f\"\\nSEX: {sex}\")\n",
    "    for _, row in group.iterrows():\n",
    "        print(f\"  {row['first_name']} {row['middle_name']} — {row['count']}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "a94a4b97-e62e-443c-8557-9136f4efc991",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- Top 10 Surname vs Middle Name Crossovers ---\n",
      "surname  middle_name\n",
      "ilunga   ilunga         1173\n",
      "         ngoy            964\n",
      "ngoyi    ngoyi           885\n",
      "kabange  numbi           830\n",
      "ngoy     mwilambwe       707\n",
      "kazadi   kazadi          663\n",
      "ilunga   kasongo         633\n",
      "kasongo  ilunga          597\n",
      "ntumba   ntumba          585\n",
      "kasongo  ngoy            575\n",
      "dtype: int64\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Crossover 3: Surname vs Middle Name\n",
    "print(\"--- Top 10 Surname vs Middle Name Crossovers ---\")\n",
    "crossover_surname_middlename = df_simple.groupby(['surname', 'middle_name']).size().sort_values(ascending=False).head(10)\n",
    "print(crossover_surname_middlename)\n",
    "print(\"\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "a9f9cec3-8285-48c4-b493-44c30f9200ad",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 105880 characters]",
      "text/plain": [
       "<Figure size 1200x1000 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# frequency of joint appearance\n",
    "top_surnames = df_simple['surname'].value_counts().head(10).index \n",
    "top_middlenames = df_simple['middle_name'].value_counts().head(10).index\n",
    "filtered_df = df_simple[\n",
    "    df_simple['surname'].isin(top_surnames) &\n",
    "    df_simple['middle_name'].isin(top_middlenames)\n",
    "]\n",
    "\n",
    "cooccurrence = filtered_df.groupby(['surname', 'middle_name']).size().unstack(fill_value=0)\n",
    "\n",
    "plt.figure(figsize=(12, 10))\n",
    "sns.heatmap(cooccurrence, annot=True, fmt='d', cmap='Oranges')\n",
    "plt.title('Heatmap of Surname vs Middle Name Cooccurrence')\n",
    "plt.xlabel('Middle Name')\n",
    "plt.ylabel('Surname')\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "131a63b8-7ed7-462a-976c-9f19c8e6c03a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- Top 10 Surname vs Middle Name Crossovers by Sex ---\n",
      "\n",
      "SEX: m\n",
      "  ilunga ilunga — 1095\n",
      "  ngoyi ngoyi — 752\n",
      "  kazadi kazadi — 626\n",
      "  kabange numbi — 587\n",
      "  ilunga ngoy — 583\n",
      "  mutombo mutombo — 538\n",
      "  ngoy mwilambwe — 528\n",
      "  mukendi mukendi — 512\n",
      "  kasongo kasongo — 492\n",
      "  kabeya kabeya — 489\n"
     ]
    }
   ],
   "source": [
    "# Crossover: Surname vs Middle Name vs Sex\n",
    "crossover_surname_middlename_sex = df_simple.groupby(['sex', 'surname', 'middle_name']).size().reset_index(name='count')\n",
    "crossover_surname_middlename_sex = crossover_surname_middlename_sex.sort_values('count', ascending=False).head(10)\n",
    "\n",
    "print(\"--- Top 10 Surname vs Middle Name Crossovers by Sex ---\")\n",
    "for sex, group in crossover_surname_middlename_sex.groupby('sex'):\n",
    "    print(f\"\\nSEX: {sex}\")\n",
    "    for _, row in group.iterrows():\n",
    "        print(f\"  {row['surname']} {row['middle_name']} — {row['count']}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "7f2d51ad-5a73-409f-8c74-8b47c5adbdd0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 59768 characters]",
      "text/plain": [
       "<Figure size 1800x600 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Calculate the length of first names, surnames, and middle names\n",
    "df['firstname_length'] = df_simple['first_name'].str.len()\n",
    "df['surname_length'] = df_simple['surname'].str.len()\n",
    "df['middlename_length'] = df_simple['middle_name'].str.len()\n",
    "\n",
    "fig, axes = plt.subplots(1, 3, figsize=(18, 6))\n",
    "\n",
    "# Histogram for firstname length\n",
    "sns.histplot(df['firstname_length'], kde=True, ax=axes[0], color='skyblue')\n",
    "axes[0].set_title('Distribution of First Name Length')\n",
    "axes[0].set_xlabel('Number of Letters')\n",
    "axes[0].set_ylabel('Frequency')\n",
    "\n",
    "# Histogram for surname length\n",
    "sns.histplot(df['surname_length'], kde=True, ax=axes[1], color='lightgreen')\n",
    "axes[1].set_title('Distribution of Surname Length')\n",
    "axes[1].set_xlabel('Number of Letters')\n",
    "axes[1].set_ylabel('Frequency')\n",
    "\n",
    "# Histogram for middle name length\n",
    "sns.histplot(df['middlename_length'], kde=True, ax=axes[2], color='salmon')\n",
    "axes[2].set_title('Distribution of Middle Name Length')\n",
    "axes[2].set_xlabel('Number of Letters')\n",
    "axes[2].set_ylabel('Frequency')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  }
 ],
 "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.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
