{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# PyFixest Benchmarks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <div id=\"4ln53B\"></div>\n",
       "            <script type=\"text/javascript\" data-lets-plot-script=\"library\">\n",
       "                if(!window.letsPlotCallQueue) {\n",
       "                    window.letsPlotCallQueue = [];\n",
       "                }; \n",
       "                window.letsPlotCall = function(f) {\n",
       "                    window.letsPlotCallQueue.push(f);\n",
       "                };\n",
       "                (function() {\n",
       "                    var script = document.createElement(\"script\");\n",
       "                    script.type = \"text/javascript\";\n",
       "                    script.src = \"https://cdn.jsdelivr.net/gh/JetBrains/lets-plot@v4.4.1/js-package/distr/lets-plot.min.js\";\n",
       "                    script.onload = function() {\n",
       "                        window.letsPlotCall = function(f) {f();};\n",
       "                        window.letsPlotCallQueue.forEach(function(f) {f();});\n",
       "                        window.letsPlotCallQueue = [];\n",
       "                        \n",
       "                    };\n",
       "                    script.onerror = function(event) {\n",
       "                        window.letsPlotCall = function(f) {};    // noop\n",
       "                        window.letsPlotCallQueue = [];\n",
       "                        var div = document.createElement(\"div\");\n",
       "                        div.style.color = 'darkred';\n",
       "                        div.textContent = 'Error loading Lets-Plot JS';\n",
       "                        document.getElementById(\"4ln53B\").appendChild(div);\n",
       "                    };\n",
       "                    var e = document.getElementById(\"4ln53B\");\n",
       "                    e.appendChild(script);\n",
       "                })()\n",
       "            </script>\n",
       "            "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "\n",
       "            <div id=\"IBBLxn\"></div>\n",
       "            <script type=\"text/javascript\" data-lets-plot-script=\"library\">\n",
       "                if(!window.letsPlotCallQueue) {\n",
       "                    window.letsPlotCallQueue = [];\n",
       "                }; \n",
       "                window.letsPlotCall = function(f) {\n",
       "                    window.letsPlotCallQueue.push(f);\n",
       "                };\n",
       "                (function() {\n",
       "                    var script = document.createElement(\"script\");\n",
       "                    script.type = \"text/javascript\";\n",
       "                    script.src = \"https://cdn.jsdelivr.net/gh/JetBrains/lets-plot@v4.4.1/js-package/distr/lets-plot.min.js\";\n",
       "                    script.onload = function() {\n",
       "                        window.letsPlotCall = function(f) {f();};\n",
       "                        window.letsPlotCallQueue.forEach(function(f) {f();});\n",
       "                        window.letsPlotCallQueue = [];\n",
       "                        \n",
       "                    };\n",
       "                    script.onerror = function(event) {\n",
       "                        window.letsPlotCall = function(f) {};    // noop\n",
       "                        window.letsPlotCallQueue = [];\n",
       "                        var div = document.createElement(\"div\");\n",
       "                        div.style.color = 'darkred';\n",
       "                        div.textContent = 'Error loading Lets-Plot JS';\n",
       "                        document.getElementById(\"IBBLxn\").appendChild(div);\n",
       "                    };\n",
       "                    var e = document.getElementById(\"IBBLxn\");\n",
       "                    e.appendChild(script);\n",
       "                })()\n",
       "            </script>\n",
       "            "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "\n",
    "import time\n",
    "\n",
    "import pandas as pd\n",
    "from linearmodels.iv import AbsorbingLS\n",
    "from tqdm import tqdm  # note: tqdm is not a dependency of pyfixest\n",
    "\n",
    "from pyfixest.estimation import feols, fepois\n",
    "\n",
    "\n",
    "def run_standard_benchmark(model, fixed_effect):\n",
    "    \"Run the standard benchmark for the fixed effect models.\"\n",
    "    assert model in [\"feols\", \"fepois\", \"absorbingls\"]\n",
    "    assert fixed_effect in [\"dum_1\", \"dum_1+dum_2\", \"dum_1+dum_2+dum_3\"]\n",
    "\n",
    "    # one fixed effect\n",
    "    res = []\n",
    "\n",
    "    fml_base = \"ln_y ~ X1\" if model == \"feols\" else \"y ~ X1\"\n",
    "    fml = f\"{fml_base} | {fixed_effect}\"\n",
    "\n",
    "    # warmup\n",
    "    df = pd.read_stata(\"./data/_STATA/base_s2_r1.dta\")\n",
    "    feols(fml, data=df)\n",
    "\n",
    "    for size in tqdm(range(1, 6)):\n",
    "        if size == 5:\n",
    "            if model == \"fepois\":\n",
    "                pass\n",
    "            else:\n",
    "                df = pd.read_csv(\"./data/data/base_10M.csv\")\n",
    "\n",
    "        for rep in range(1, 11):\n",
    "            if size < 5:\n",
    "                df = pd.read_stata(f\"./data/_STATA/base_s{size}_r{rep}.dta\")\n",
    "\n",
    "            tic = time.time()\n",
    "            if model == \"feols\":\n",
    "                feols(fml, data=df)\n",
    "            elif model == \"absorbingls\":\n",
    "                df = df.astype({f\"dum_{i}\": \"category\" for i in range(1, 4)})\n",
    "                df_exog = df[[\"X1\"]]\n",
    "\n",
    "                absorb_columns = fixed_effect.split(\"+\")\n",
    "                df_absorb = df[absorb_columns]\n",
    "                df_endog = df[\"ln_y\"]\n",
    "                # I don't think the approach gives analogous standard errors\n",
    "                AbsorbingLS(df_endog, df_exog, absorb=df_absorb).fit(\n",
    "                    cov_type=\"clustered\"\n",
    "                )\n",
    "            else:\n",
    "                fepois(fml, data=df)\n",
    "            toc = time.time()\n",
    "\n",
    "            res.append(\n",
    "                pd.Series(\n",
    "                    {\n",
    "                        \"method\": model,\n",
    "                        \"n_obs\": df.shape[0],\n",
    "                        \"G\": len(fixed_effect.split(\"+\")),\n",
    "                        \"rep\": rep,\n",
    "                        \"time\": toc - tic,\n",
    "                    }\n",
    "                )\n",
    "            )\n",
    "\n",
    "    return pd.concat(res, axis=1).T\n",
    "\n",
    "\n",
    "def run_all_benchmarks():\n",
    "    \"Run all the benchmarks.\"\n",
    "    res = pd.DataFrame()\n",
    "    for model in [\"feols\", \"fepois\", \"absorbingls\"]:\n",
    "        for fixef in [\"dum_1\", \"dum_1+dum_2\", \"dum_1+dum_2+dum_3\"]:\n",
    "            res = pd.concat([res, run_standard_benchmark(model, fixef)], axis=0)\n",
    "\n",
    "    res.to_csv(\"./results_py.csv\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 5/5 [00:23<00:00,  4.76s/it]\n",
      "100%|██████████| 5/5 [00:28<00:00,  5.67s/it]\n",
      "100%|██████████| 5/5 [00:30<00:00,  6.18s/it]\n",
      "  0%|          | 0/5 [00:00<?, ?it/s]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 15 observations removed because of separation.\n",
      "  warnings.warn(\n",
      " 20%|██        | 1/5 [00:01<00:05,  1.34s/it]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 19 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 15 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 14 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 50 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 28 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 30 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 59 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 27 observations removed because of separation.\n",
      "  warnings.warn(\n",
      " 40%|████      | 2/5 [00:02<00:02,  1.02it/s]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 344 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 367 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 126 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 212 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 702 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 155 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 70 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 457 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 197 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 196 observations removed because of separation.\n",
      "  warnings.warn(\n",
      " 60%|██████    | 3/5 [00:03<00:02,  1.26s/it]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1645 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 3018 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 3068 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1682 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1768 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1302 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 2236 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 2304 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1686 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      " 80%|████████  | 4/5 [00:14<00:05,  5.06s/it]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "100%|██████████| 5/5 [00:25<00:00,  5.04s/it]\n",
      "  0%|          | 0/5 [00:00<?, ?it/s]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 15 observations removed because of separation.\n",
      "  warnings.warn(\n",
      " 20%|██        | 1/5 [00:01<00:05,  1.35s/it]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 19 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 15 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 14 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 50 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 28 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 30 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 59 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 27 observations removed because of separation.\n",
      "  warnings.warn(\n",
      " 40%|████      | 2/5 [00:02<00:03,  1.11s/it]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 344 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 367 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 126 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 212 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 702 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 155 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 70 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 457 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 197 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 196 observations removed because of separation.\n",
      "  warnings.warn(\n",
      " 60%|██████    | 3/5 [00:04<00:03,  1.82s/it]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1645 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 3018 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 3068 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1682 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1768 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1302 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 2236 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 2304 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1686 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      " 80%|████████  | 4/5 [00:33<00:12, 12.33s/it]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "100%|██████████| 5/5 [01:06<00:00, 13.37s/it]\n",
      "  0%|          | 0/5 [00:00<?, ?it/s]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 15 observations removed because of separation.\n",
      "  warnings.warn(\n",
      " 20%|██        | 1/5 [00:00<00:02,  1.44it/s]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 19 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 15 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 14 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 50 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 28 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 30 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 59 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 27 observations removed because of separation.\n",
      "  warnings.warn(\n",
      " 40%|████      | 2/5 [00:01<00:02,  1.09it/s]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 344 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 367 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 126 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 212 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 702 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 155 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 70 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 457 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 197 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 196 observations removed because of separation.\n",
      "  warnings.warn(\n",
      " 60%|██████    | 3/5 [00:05<00:04,  2.15s/it]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1645 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 3018 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 3068 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1682 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1768 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1302 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 2236 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 2304 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1686 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      " 80%|████████  | 4/5 [00:48<00:18, 18.50s/it]/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "/Users/marc/Documents/pyfixest/pyfixest/estimation/fepois_.py:139: UserWarning: 1631 observations removed because of separation.\n",
      "  warnings.warn(\n",
      "100%|██████████| 5/5 [01:43<00:00, 20.69s/it]\n",
      "100%|██████████| 5/5 [37:23<00:00, 448.78s/it]\n",
      "100%|██████████| 5/5 [1:26:09<00:00, 1033.99s/it]\n",
      "100%|██████████| 5/5 [1:44:48<00:00, 1257.66s/it]\n"
     ]
    }
   ],
   "source": [
    "run_all_benchmarks()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 5/5 [16:53<00:00, 202.62s/it]\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>method</th>\n",
       "      <th>n_obs</th>\n",
       "      <th>G</th>\n",
       "      <th>rep</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.056183</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>0.05277</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>0.052286</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000</td>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>0.052665</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000</td>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "      <td>0.052282</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000</td>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>0.052521</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>0.052853</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000</td>\n",
       "      <td>1</td>\n",
       "      <td>8</td>\n",
       "      <td>0.053038</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000</td>\n",
       "      <td>1</td>\n",
       "      <td>9</td>\n",
       "      <td>0.053121</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000</td>\n",
       "      <td>1</td>\n",
       "      <td>10</td>\n",
       "      <td>0.052397</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.054689</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>0.053319</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>0.054951</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000</td>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>0.053898</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000</td>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "      <td>0.05422</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000</td>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>0.055358</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>0.054344</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000</td>\n",
       "      <td>1</td>\n",
       "      <td>8</td>\n",
       "      <td>0.0599</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000</td>\n",
       "      <td>1</td>\n",
       "      <td>9</td>\n",
       "      <td>0.056684</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000</td>\n",
       "      <td>1</td>\n",
       "      <td>10</td>\n",
       "      <td>0.054084</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>feols</td>\n",
       "      <td>100000</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.064738</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>feols</td>\n",
       "      <td>100000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>0.062995</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>feols</td>\n",
       "      <td>100000</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>0.064231</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>feols</td>\n",
       "      <td>100000</td>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>0.063408</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>feols</td>\n",
       "      <td>100000</td>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "      <td>0.063151</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>feols</td>\n",
       "      <td>100000</td>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>0.065336</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26</th>\n",
       "      <td>feols</td>\n",
       "      <td>100000</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>0.064017</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>feols</td>\n",
       "      <td>100000</td>\n",
       "      <td>1</td>\n",
       "      <td>8</td>\n",
       "      <td>0.063007</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>feols</td>\n",
       "      <td>100000</td>\n",
       "      <td>1</td>\n",
       "      <td>9</td>\n",
       "      <td>0.065574</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>feols</td>\n",
       "      <td>100000</td>\n",
       "      <td>1</td>\n",
       "      <td>10</td>\n",
       "      <td>0.06459</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>30</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000000</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.180321</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>31</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>0.18074</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>32</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000000</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>0.178868</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>33</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000000</td>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>0.175977</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>34</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000000</td>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "      <td>0.175205</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>35</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000000</td>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>0.178113</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>36</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000000</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>0.175998</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>37</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000000</td>\n",
       "      <td>1</td>\n",
       "      <td>8</td>\n",
       "      <td>0.178389</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>38</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000000</td>\n",
       "      <td>1</td>\n",
       "      <td>9</td>\n",
       "      <td>0.17657</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>39</th>\n",
       "      <td>feols</td>\n",
       "      <td>1000000</td>\n",
       "      <td>1</td>\n",
       "      <td>10</td>\n",
       "      <td>0.172102</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>40</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000000</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>992.064057</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>41</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>1.935793</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>42</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000000</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>1.74646</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>43</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000000</td>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>1.726809</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>44</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000000</td>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "      <td>1.662941</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>45</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000000</td>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>1.64592</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>46</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000000</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>1.652289</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>47</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000000</td>\n",
       "      <td>1</td>\n",
       "      <td>8</td>\n",
       "      <td>1.667719</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>48</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000000</td>\n",
       "      <td>1</td>\n",
       "      <td>9</td>\n",
       "      <td>1.649755</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>49</th>\n",
       "      <td>feols</td>\n",
       "      <td>10000000</td>\n",
       "      <td>1</td>\n",
       "      <td>10</td>\n",
       "      <td>1.645669</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   method     n_obs  G rep        time\n",
       "0   feols      1000  1   1    0.056183\n",
       "1   feols      1000  1   2     0.05277\n",
       "2   feols      1000  1   3    0.052286\n",
       "3   feols      1000  1   4    0.052665\n",
       "4   feols      1000  1   5    0.052282\n",
       "5   feols      1000  1   6    0.052521\n",
       "6   feols      1000  1   7    0.052853\n",
       "7   feols      1000  1   8    0.053038\n",
       "8   feols      1000  1   9    0.053121\n",
       "9   feols      1000  1  10    0.052397\n",
       "10  feols     10000  1   1    0.054689\n",
       "11  feols     10000  1   2    0.053319\n",
       "12  feols     10000  1   3    0.054951\n",
       "13  feols     10000  1   4    0.053898\n",
       "14  feols     10000  1   5     0.05422\n",
       "15  feols     10000  1   6    0.055358\n",
       "16  feols     10000  1   7    0.054344\n",
       "17  feols     10000  1   8      0.0599\n",
       "18  feols     10000  1   9    0.056684\n",
       "19  feols     10000  1  10    0.054084\n",
       "20  feols    100000  1   1    0.064738\n",
       "21  feols    100000  1   2    0.062995\n",
       "22  feols    100000  1   3    0.064231\n",
       "23  feols    100000  1   4    0.063408\n",
       "24  feols    100000  1   5    0.063151\n",
       "25  feols    100000  1   6    0.065336\n",
       "26  feols    100000  1   7    0.064017\n",
       "27  feols    100000  1   8    0.063007\n",
       "28  feols    100000  1   9    0.065574\n",
       "29  feols    100000  1  10     0.06459\n",
       "30  feols   1000000  1   1    0.180321\n",
       "31  feols   1000000  1   2     0.18074\n",
       "32  feols   1000000  1   3    0.178868\n",
       "33  feols   1000000  1   4    0.175977\n",
       "34  feols   1000000  1   5    0.175205\n",
       "35  feols   1000000  1   6    0.178113\n",
       "36  feols   1000000  1   7    0.175998\n",
       "37  feols   1000000  1   8    0.178389\n",
       "38  feols   1000000  1   9     0.17657\n",
       "39  feols   1000000  1  10    0.172102\n",
       "40  feols  10000000  1   1  992.064057\n",
       "41  feols  10000000  1   2    1.935793\n",
       "42  feols  10000000  1   3     1.74646\n",
       "43  feols  10000000  1   4    1.726809\n",
       "44  feols  10000000  1   5    1.662941\n",
       "45  feols  10000000  1   6     1.64592\n",
       "46  feols  10000000  1   7    1.652289\n",
       "47  feols  10000000  1   8    1.667719\n",
       "48  feols  10000000  1   9    1.649755\n",
       "49  feols  10000000  1  10    1.645669"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = run_standard_benchmark(\"feols\", \"dum_1\")\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "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>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "      <th>5</th>\n",
       "      <th>6</th>\n",
       "      <th>7</th>\n",
       "      <th>8</th>\n",
       "      <th>9</th>\n",
       "      <th>...</th>\n",
       "      <th>40</th>\n",
       "      <th>41</th>\n",
       "      <th>42</th>\n",
       "      <th>43</th>\n",
       "      <th>44</th>\n",
       "      <th>45</th>\n",
       "      <th>46</th>\n",
       "      <th>47</th>\n",
       "      <th>48</th>\n",
       "      <th>49</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>method</th>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>...</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "      <td>feols</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>n_obs</th>\n",
       "      <td>1000</td>\n",
       "      <td>1000</td>\n",
       "      <td>1000</td>\n",
       "      <td>1000</td>\n",
       "      <td>1000</td>\n",
       "      <td>1000</td>\n",
       "      <td>1000</td>\n",
       "      <td>1000</td>\n",
       "      <td>1000</td>\n",
       "      <td>1000</td>\n",
       "      <td>...</td>\n",
       "      <td>10000000</td>\n",
       "      <td>10000000</td>\n",
       "      <td>10000000</td>\n",
       "      <td>10000000</td>\n",
       "      <td>10000000</td>\n",
       "      <td>10000000</td>\n",
       "      <td>10000000</td>\n",
       "      <td>10000000</td>\n",
       "      <td>10000000</td>\n",
       "      <td>10000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>G</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>rep</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>3</td>\n",
       "      <td>4</td>\n",
       "      <td>5</td>\n",
       "      <td>6</td>\n",
       "      <td>7</td>\n",
       "      <td>8</td>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>3</td>\n",
       "      <td>4</td>\n",
       "      <td>5</td>\n",
       "      <td>6</td>\n",
       "      <td>7</td>\n",
       "      <td>8</td>\n",
       "      <td>9</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>time</th>\n",
       "      <td>0.056183</td>\n",
       "      <td>0.05277</td>\n",
       "      <td>0.052286</td>\n",
       "      <td>0.052665</td>\n",
       "      <td>0.052282</td>\n",
       "      <td>0.052521</td>\n",
       "      <td>0.052853</td>\n",
       "      <td>0.053038</td>\n",
       "      <td>0.053121</td>\n",
       "      <td>0.052397</td>\n",
       "      <td>...</td>\n",
       "      <td>992.064057</td>\n",
       "      <td>1.935793</td>\n",
       "      <td>1.74646</td>\n",
       "      <td>1.726809</td>\n",
       "      <td>1.662941</td>\n",
       "      <td>1.64592</td>\n",
       "      <td>1.652289</td>\n",
       "      <td>1.667719</td>\n",
       "      <td>1.649755</td>\n",
       "      <td>1.645669</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 50 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "              0        1         2         3         4         5         6   \\\n",
       "method     feols    feols     feols     feols     feols     feols     feols   \n",
       "n_obs       1000     1000      1000      1000      1000      1000      1000   \n",
       "G              1        1         1         1         1         1         1   \n",
       "rep            1        2         3         4         5         6         7   \n",
       "time    0.056183  0.05277  0.052286  0.052665  0.052282  0.052521  0.052853   \n",
       "\n",
       "              7         8         9   ...          40        41        42  \\\n",
       "method     feols     feols     feols  ...       feols     feols     feols   \n",
       "n_obs       1000      1000      1000  ...    10000000  10000000  10000000   \n",
       "G              1         1         1  ...           1         1         1   \n",
       "rep            8         9        10  ...           1         2         3   \n",
       "time    0.053038  0.053121  0.052397  ...  992.064057  1.935793   1.74646   \n",
       "\n",
       "              43        44        45        46        47        48        49  \n",
       "method     feols     feols     feols     feols     feols     feols     feols  \n",
       "n_obs   10000000  10000000  10000000  10000000  10000000  10000000  10000000  \n",
       "G              1         1         1         1         1         1         1  \n",
       "rep            4         5         6         7         8         9        10  \n",
       "time    1.726809  1.662941   1.64592  1.652289  1.667719  1.649755  1.645669  \n",
       "\n",
       "[5 rows x 50 columns]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.T"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualisation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "res_all = pd.concat(\n",
    "    [\n",
    "        pd.read_csv(\"./results_py.csv\"),\n",
    "        pd.read_csv(\"./results_all.txt\"),\n",
    "    ]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
