From fd4181262543a02bfc5ed4ef801c764dad1ffdbc Mon Sep 17 00:00:00 2001 From: Elouen Ginat Date: Tue, 14 Apr 2026 18:08:29 +0200 Subject: [PATCH] Refactor code structure for improved readability and maintainability --- pyproject.toml | 2 +- sandbox/khisto_demo.ipynb | 94 +++++++-------------------------------- 2 files changed, 16 insertions(+), 80 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index df00d17..b51ec5c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "khisto" -version = "0.1.0" +version = "0.2.0" description = "Optimal histogram visualization using the Khiops algorithm" readme = "README.md" license = "BSD-3-Clause-Clear" diff --git a/sandbox/khisto_demo.ipynb b/sandbox/khisto_demo.ipynb index 9bb3379..e17241a 100644 --- a/sandbox/khisto_demo.ipynb +++ b/sandbox/khisto_demo.ipynb @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 1, "id": "e24a8a4b", "metadata": {}, "outputs": [ @@ -53,7 +53,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 2, "id": "56410772", "metadata": {}, "outputs": [ @@ -80,7 +80,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 3, "id": "1b7d0305", "metadata": {}, "outputs": [ @@ -118,7 +118,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 4, "id": "2749c664", "metadata": {}, "outputs": [ @@ -142,7 +142,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 5, "id": "1cca2392", "metadata": {}, "outputs": [ @@ -164,7 +164,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 6, "id": "2ad6d7e5", "metadata": {}, "outputs": [ @@ -184,70 +184,6 @@ "print(f\"Bin edges: {edges_range}\")" ] }, - { - "cell_type": "markdown", - "id": "79097e35", - "metadata": {}, - "source": [ - "### Cumulative histogram with `khisto.cumfreq`\n", - "\n", - "Use `cumfreq` when you want cumulative counts or a cumulative distribution function with the same adaptive binning strategy." - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "6709dafb", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Final cumulative count: 1000\n", - "Number of cumulative bins: 7\n", - "Last CDF value: 1.000000\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAGGCAYAAACqvTJ0AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAYlpJREFUeJzt3XmcjfX///HnGWMWy8wYs9kNKWSZkLWQJmPNSGXLloiMbSim7AqpJLJEhYpQIZ/4kA9ZstZYiuyNpjCDLIOYMTPX749+ztcxgzmcc64x87jfbnP7OO/rfa7reZ1LH6/ba67zviyGYRgCAAAAAAAAXMjN7AAAAAAAAADIfWhKAQAAAAAAwOVoSgEAAAAAAMDlaEoBAAAAAADA5WhKAQAAAAAAwOVoSgEAAAAAAMDlaEoBAAAAAADA5WhKAQAAAAAAwOVoSgEAAAAAAMDlaEoB95G5c+fKYrHo2LFjphy/a9euKl26tCnHvh+tX79eFotF69evd+h+LRaLRo0a5dB9AgBwP6I2ur/khtro2LFjslgsmjt3rtlRstXnAtwKTSnABNOnT5fFYlGtWrXMjpLBiRMnNGrUKO3evdvsKLnaypUrKSLsNH369GxRAAIA7EdthDuhNrp3W7Zs0ahRo3T+/HmzowBWNKUAE8yfP1+lS5fWjh07dOTIEbPj2Dhx4oRGjx6daeE1e/ZsHTx40PWhcqGVK1dq9OjRmW67cuWKhg0b5uJE2R9NKQC4f1Eb4U6ojex38+eyZcsWjR49mqYUshWaUoCLxcXFacuWLZo0aZICAwM1f/58syNlWd68eeXp6Wl2jFzPy8tL7u7uZscAAMAhqI1wr6iNMsfngvsBTSnAxebPn69ChQqpefPmevbZZ29ZeO3bt0+NGjWSt7e3ihcvrjfffFPp6ekZ5n377bdq3ry5ihYtKk9PT5UtW1Zjx45VWlqazbyGDRuqUqVKio2NVd26deXt7a3Q0FDNnDnTOmf9+vV69NFHJUndunWTxWKx+U78jesmXLt2Tf7+/urWrVuGTElJSfLy8tLgwYOtY8nJyRo5cqQeeOABeXp6qkSJEnrttdeUnJycpc9t+/btatasmQoVKqT8+fOrSpUq+uCDD2zOr2HDhhned/NaD9e/5//uu+9q2rRpKlOmjPLly6fGjRvrzz//lGEYGjt2rIoXLy5vb2+1atVKZ8+etdnnrb6fX7p0aXXt2vW257Fp0yY999xzKlmypPVzGDhwoK5cuWKTedq0adZjXf/J7Phff/21LBaLNmzYkOFYH330kSwWi/bu3WsdO3DggJ599ln5+/vLy8tLNWrU0PLly2+b+br09HR98MEHqly5sry8vBQYGKgmTZro559/ts5JTU3V2LFjVbZsWXl6eqp06dJ6/fXXM1znrH6G19cK2bx5s6KjoxUYGKj8+fOrdevWOn36tM379u3bpw0bNlg/r+t/H65du6bRo0erXLly8vLyUuHChfXYY49pzZo1WTpvAIBzURtRG92vtdH58+fVtWtX+fr6ys/PT126dLnlXUhZOU5W6x5J+vnnnxUREaGAgADr390XX3zRZs6Nn8uoUaP06quvSpJCQ0Otn+GxY8fUoEEDVa1aNdPcDz30kCIiIrL0eQB3g7Yp4GLz58/XM888Iw8PD7Vv314zZszQTz/9ZC14JCkhIUFPPPGEUlNTNXToUOXPn1+zZs2St7d3hv3NnTtXBQoUUHR0tAoUKKB169ZpxIgRSkpK0jvvvGMz99y5c2rWrJmef/55tW/fXosXL1bv3r3l4eGhF198URUqVNCYMWM0YsQI9ezZU48//rgkqW7duhmOmzdvXrVu3VpLlizRRx99JA8PD+u2ZcuWKTk5We3atZP0bzPj6aef1o8//qiePXuqQoUK+vXXX/X+++/r0KFDWrZs2W0/szVr1qhFixYqUqSI+vfvr5CQEO3fv1/fffed+vfvn+XP/kbz589XSkqK+vbtq7Nnz2rixIl6/vnn1ahRI61fv15DhgzRkSNHNHXqVA0ePFiffvrpXR3nZl999ZX++ecf9e7dW4ULF9aOHTs0depU/fXXX/rqq68kSS+//LJOnDihNWvW6PPPP7/t/po3b64CBQpo8eLFatCggc22RYsW6eGHH1alSpUk/VvM16tXT8WKFbP+vVq8eLEiIyP1zTffqHXr1rc9Vvfu3TV37lw1bdpUL730klJTU7Vp0yZt27ZNNWrUkCS99NJLmjdvnp599lkNGjRI27dv1/jx47V//34tXbr0bj829e3bV4UKFdLIkSN17NgxTZ48WVFRUVq0aJEkafLkyerbt68KFCigN954Q5IUHBws6d8ibPz48XrppZdUs2ZNJSUl6eeff9bOnTv11FNP3XUmAIBjUBtRG92PtZFhGGrVqpV+/PFH9erVSxUqVNDSpUvVpUuXDHPtPc6d6p5Tp06pcePGCgwM1NChQ+Xn56djx45pyZIlt8z7zDPP6NChQ/ryyy/1/vvvKyAgQJIUGBioTp06qUePHtq7d6/1s5Gkn376SYcOHeKrkXAuA4DL/Pzzz4YkY82aNYZhGEZ6erpRvHhxo3///jbzBgwYYEgytm/fbh07deqU4evra0gy4uLirOP//PNPhuO8/PLLRr58+YyrV69axxo0aGBIMt577z3rWHJyshEWFmYEBQUZKSkphmEYxk8//WRIMubMmZNhv126dDFKlSplfb169WpDkvGf//zHZl6zZs2MMmXKWF9//vnnhpubm7Fp0yabeTNnzjQkGZs3b85wrOtSU1ON0NBQo1SpUsa5c+dstqWnp9ucX4MGDe6YOS4uzpBkBAYGGufPn7eOx8TEGJKMqlWrGteuXbOOt2/f3vDw8LD5LCUZI0eOzHCsUqVKGV26dLG+/uGHHwxJxg8//GAdy+x6jR8/3rBYLMYff/xhHevTp49xq/+Lvvn47du3N4KCgozU1FTr2MmTJw03NzdjzJgx1rEnn3zSqFy5ss25pKenG3Xr1jXKlSuX6bGuW7dunSHJ6NevX4Zt16/D7t27DUnGSy+9ZLN98ODBhiRj3bp1tzyH627+DOfMmWNIMsLDw22u98CBA408efLYXMOHH344078DVatWNZo3b37b8wMAmIPaiNrofq2Nli1bZkgyJk6caB1LTU01Hn/88Qx/X7J6nKzWPUuXLjUkGT/99NNtM978ubzzzjsZ/nsxDMM4f/684eXlZQwZMsRmvF+/fkb+/PmNS5cu3fY4wL3g63uAC82fP1/BwcF64oknJP17S23btm21cOFCm1vKV65cqdq1a6tmzZrWscDAQHXs2DHDPm/8DeHFixd15swZPf744/rnn3904MABm7nu7u56+eWXra89PDz08ssv69SpU4qNjbX7fBo1aqSAgADrb22kf3/juGbNGrVt29Y69tVXX6lChQoqX768zpw5Y/1p1KiRJOmHH3645TF27dqluLg4DRgwQH5+fjbbbrxt217PPfecfH19ra+vP+3nhRdesPnufa1atZSSkqLjx4/f9bFudOP1unz5ss6cOaO6devKMAzt2rXrrvbZtm1bnTp1yubxyl9//bXS09Ot1+Hs2bNa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n5+fZs6cqYIFCyp//vyqVauWzT/iN2vbtq2mTp2qkSNHqnLlyjZ3yUj//gO3ePFi9erVSz/88IPq1auntLQ0HThwQIsXL9bq1atVo0aNTPft5uamGTNmqGXLlgoLC1O3bt1UpEgRHThwQPv27dPq1aslSS+++KImTZqkiIgIde/eXadOndLMmTP18MMPKykp6dYX5y689NJL6tWrl9q0aaOnnnpKe/bs0erVq62P1r2V8uXLq2zZsho8eLCOHz8uHx8fffPNN5muyXC9EO7Xr58iIiKUJ08e62OkM5M3b14988wzWrhwoS5fvqx33303w5xp06bpscceU+XKldWjRw+VKVNGiYmJ2rp1q/766y/t2bPnlvt/4okn1KlTJ02ZMkWHDx9WkyZNlJ6erk2bNumJJ55QVFSUqlatqi5dumjWrFnWr0/s2LFD8+bNU2RkpHUR23v5DG+nevXqmjFjht5880098MADCgoKUqNGjVSxYkU1bNhQ1atXl7+/v37++Wd9/fXXioqKuutjAQDuDbURtZF0f9dGLVu2VL169TR06FAdO3ZMFStW1JIlSzJdB+tejpOZefPmafr06WrdurXKli2rixcvavbs2fLx8bH+kjAz1z/DN954Q+3atVPevHnVsmVLa7PqkUceUaVKlawL8VerVs2uXMBdcdFT/oBcrWXLloaXl5dx+fLlW87p2rWrkTdvXuPMmTOGYRjGL7/8YjRo0MDw8vIyihUrZowdO9b45JNPMjzGdfPmzUbt2rUNb29vo2jRosZrr71mfRzxjY/bbdCggfHwww8bP//8s1GnTh3Dy8vLKFWqlPHhhx9myPLtt98aFStWNNzd3W0eaXvzI4SvS09PN0qUKGFIMt58881Mzy8lJcV4++23jYcfftjw9PQ0ChUqZFSvXt0YPXq0ceHChTt+hj/++KPx1FNPGQULFjTy589vVKlSxZg6darNnC+++MIoU6aM4eHhYYSFhRmrV6++5WOP33nnHZv3Xn9E8VdffWUzfv3RvDc+cjctLc0YMmSIERAQYOTLl8+IiIgwjhw5kqXHHv/2229GeHi4UaBAASMgIMDo0aOHsWfPngyPDk5NTTX69u1rBAYGGhaLxeYRyLrFY5fXrFljSDIsFovx559/Zvo5Hj161OjcubMREhJi5M2b1yhWrJjRokUL4+uvv850/o1SU1ON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E7vvlPL19dWWLVu0Zs0a7dmzR97e3qpSpYrq16/v8HC///67ZsyYoejoaL3++uv66aef1K9fP3l4eKhLly5KSEiQJAUHB9u8Lzg42LotISFBQUFBNtvd3d3l7+9vnXOz5ORkJScnW18nJSU58rQAAACs9u/fr8WLF2cYf/HFFzV58uQs7+fMmTNKS0vLtC46cOBApu/5/ffftW7dOnXs2FErV67UkSNH9Morr+jatWsaOXJkpu+hTgIAAI5id1NKkiwWixo3bqzGjRs7Oo+N9PR01ahRQ+PGjZMkPfLII9q7d69mzpypLl26OO2448eP1+jRo522fwAAgOsCAwO1e/dulStXzmZ89+7dGX6x5mjp6ekKCgrSrFmzlCdPHlWvXl3Hjx/XO++8c8umFHUSAABwFLu/vudKRYoUyfCkvwoVKig+Pl6SFBISIklKTEy0mZOYmGjdFhISkmFxz9TUVJ09e9Y652YxMTG6cOGC9efPP/90yPkAAADcrEePHurZs6fefvttbdq0SZs2bdKECRP08ssvq0ePHlneT0BAgPLkyXPbuuhmRYoU0YMPPqg8efJYxypUqKCEhASlpKRk+h7qJAAA4CjZuilVr149HTx40Gbs0KFD1scjh4aGKiQkRGvXrrVuT0pK0vbt21WnTh1JUp06dXT+/HnFxsZa56xbt07p6emqVatWpsf19PSUj4+PzQ8AAIAzDB8+XCNGjNDUqVPVoEEDNWjQQB9++KFGjRqlYcOGZXk/Hh4eql69uk1dlJ6errVr11rropvVq1dPR44cUXp6unXs0KFDKlKkiDw8PDJ9D3USAABwlGzdlBo4cKC2bdumcePG6ciRI1qwYIFmzZqlPn36SPr3a4QDBgzQm2++qeXLl+vXX39V586dVbRoUUVGRkr697d9TZo0UY8ePbRjxw5t3rxZUVFRateuHU/eAwAApkpNTdXnn3+uDh066K+//rLeffTXX3+pf//+slgsdu0vOjpas2fP1rx587R//3717t1bly9ftj6Nr3PnzoqJibHO7927t86ePav+/fvr0KFDWrFihcaNG2ettQAAAJzprtaUcpVHH31US5cuVUxMjMaMGaPQ0FBNnjxZHTt2tM557bXXdPnyZfXs2VPnz5/XY489plWrVsnLy8s6Z/78+YqKitKTTz4pNzc3tWnTRlOmTDHjlAAAAKzc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+SsXdTU1WeOaRalM4WJmxzGFn3dBFfHhl3cAkBUOW1MKyHX8K0jB1cxOAQC4z82fP1+zZ89W8+bNNWrUKLVv315ly5ZVlSpVtG3bNvXr18/siIDdyhQupgrBoWbHAABkc272vuHq1at655131KxZM9WoUUPVqlWz+XGmCRMmyGKxaMCAATZ5+vTpo8KFC6tAgQJq06aNEhMTbd4XHx+v5s2bK1++fAoKCtKrr76q1NRUp2YFAADIioSEBFWuXFmSVKBAAeuDY1q0aKEVK1bc1T6nTZum0qVLy8vLS7Vq1dKOHTuy9L6FCxfKYrFYnwwIAADgTHbfKdW9e3d9//33evbZZ1WzZk1ZLBZn5Mrgp59+0kcffaQqVarYjA8cOFArVqzQV199JV9fX0VFRemZZ57R5s2bJf27TkPz5s0VEhKiLVu26OTJk+rcubPy5s2rcePGuSQ7AADArRQvXlwnT55UyZIlVbZsWX3//feqVq2afvrpJ3l6etq9v0WLFik6OlozZ85UrVq1NHnyZEVEROjgwYMKCgq65fuOHTumwYMH6/HHH7+X0wEAAMgyu5tS3333nVauXKl69eo5I0+mLl26pI4dO2r27Nl68803reMXLlzQJ598ogULFqhRo0aSpDlz5qhChQratm2bateure+//16//fab/ve//yk4OFhhYWEaO3ashgwZolGjRsnDw8Nl5wEAAHCz1q1ba+3atapVq5b69u2rF154QZ988oni4+M1cOBAu/c3adIk9ejRQ926dZMkzZw5UytWrNCnn36qoUOHZvqetLQ0dezYUaNHj9amTZt0/vz5ezklAACALLH763vFihVTwYKufZpEnz591Lx5c4WHh9uMx8bG6tq1azbj5cuXV8mSJbV161ZJ0tatW1W5cmUFBwdb50RERCgpKUn79u1zzQkAAADcwoQJE/T6669Lktq2bauNGzeqd+/e+vrrrzVhwgS79pWSkqLY2Fib2sjNzU3h4eHW2igzY8aMUVBQkLp37353JwEAAHAX7L5T6r333tOQIUM0c+ZMlSpVyhmZbCxcuFA7d+7UTz/9lGFbQkKCPDw85OfnZzMeHByshIQE65wbG1LXt1/flpnk5GQlJ//fY2yTkpLu5RQAAACyrE6dOqpTp85dvffMmTNKS0vLtPY5cOBApu/58ccf9cknn2j37t1ZOgZ1EgAAcBS7m1I1atTQ1atXVaZMGeXLl0958+a12X727FmHhfvzzz/Vv39/rVmzRl5eXg7b752MHz9eo0ePdtnxAABA7rJ8+fIsz3366aedluPixYvq1KmTZs+erYCArD3CnjoJAAA4it1Nqfbt2+v48eMaN26cgoODnbrQeWxsrE6dOmXzVL+0tDRt3LhRH374oVavXq2UlBSdP3/e5m6pxMREhYSESJJCQkIyPHHm+tP5rs+5WUxMjKKjo62vk5KSVKJECUedFgAAyOWy+nQ7i8WitLS0LO83ICBAefLkyfAk4htroxsdPXpUx44dU8uWLa1j6enpkiR3d3cdPHhQZcuWtXkPdRIAAHAUu5tSW7Zs0datW1W1alVn5LHx5JNP6tdff7UZ69atm8qXL68hQ4aoRIkSyps3r9auXas2bdpIkg4ePKj4+Hjrbe916tTRW2+9pVOnTlmfOLNmzRr5+PioYsWKmR7X09Pzrp52AwAAkBXXGz+O5uHhoerVq2vt2rXWxld6errWrl2rqKioDPPLly+fodYaNmyYLl68qA8++CDTZhN1EgAAcBS7m1Lly5fXlStXnJElg4IFC6pSpUo2Y/nz51fhwoWt4927d1d0dLT8/f3l4+Ojvn37qk6dOqpdu7YkqXHjxqpYsaI6deqkiRMnKiEhQcOGDVOfPn0oqAAAQI4THR2tLl26qEaNGqpZs6YmT56sy5cvW5/G17lzZxUrVkzjx4+Xl5dXhlrr+t3nN48DAAA4mt1NqQkTJmjQoEF66623VLly5QxrSvn4+DgsXFa8//77cnNzU5s2bZScnKyIiAhNnz7duj1Pnjz67rvv1Lt3b9WpU0f58+dXly5dNGbMGJfmBAAAyMydapIRI0bYtb+2bdvq9OnTGjFihBISEhQWFqZVq1ZZFz+Pj4+Xm5vdD2AGAABwOLubUk2aNJH071frbmQYht3rHtyN9evX27z28vLStGnTNG3atFu+p1SpUlq5cqVTcwEAANyNpUuX2ry+du2a4uLi5O7urrJly9rdlJKkqKioTL+uJ2WspW42d+5cu48HAABwN+xuSv3www/OyAEAAJAr7dq1K8NYUlKSunbtqtatW5uQCAAAwDXsbko1aNDAGTkAAADw//n4+Gj06NFq2bKlOnXqZHYcAAAAp7C7KbVx48bbbq9fv/5dhwEAAMC/Lly4oAsXLpgdAwAAwGnsbko1bNgww5jFYrH+2dlrSgEAAOQkU6ZMsXltGIZOnjypzz//XE2bNjUpFQAAgPPZ3ZQ6d+6czetr165p165dGj58uN566y2HBQMAAMgN3n//fZvXbm5uCgwMVJcuXRQTE2NSKgAAAOezuynl6+ubYeypp56Sh4eHoqOjFRsb65BgAAAAuUFcXJzZEQAAAEzh5qgdBQcH6+DBg47aHQAAAAAAAHIwu++U+uWXX2xeX1/3YMKECQoLC3NULgAAgFzh6tWrmjp1qn744QedOnVK6enpNtt37txpUjIAAADnsrspFRYWJovFIsMwbMZr166tTz/91GHBAAAAcoPu3bvr+++/17PPPquaNWvaPEAGAAAgJ7O7KXXzugfXF+P08vJyWCgAAIDc4rvvvtPKlStVr149s6MAAAC4lN1NqVKlSjkjBwAAQK5UrFgxFSxY0OwYAAAALpflhc7XrVunihUrKikpKcO2Cxcu6OGHH9amTZscGg4AACCne++99zRkyBD98ccfZkcBAABwqSw3pSZPnqwePXrIx8cnwzZfX1+9/PLLmjRpkkPDAQAA5HQ1atTQ1atXVaZMGRUsWFD+/v42PwAAADlVlr++t2fPHr399tu33N64cWO9++67DgkFAACQW7Rv317Hjx/XuHHjFBwczELnAAAg18hyUyoxMVF58+a99Y7c3XX69GmHhAIAAMgttmzZoq1bt6pq1apmRwEAAHCpLH99r1ixYtq7d+8tt//yyy8qUqSIQ0IBAADkFuXLl9eVK1fMjgEAAOByWW5KNWvWTMOHD9fVq1czbLty5YpGjhypFi1aODQcAABATjdhwgQNGjRI69ev199//62kpCSbHwAAgJwqy1/fGzZsmJYsWaIHH3xQUVFReuihhyRJBw4c0LRp05SWlqY33njDaUEBAAByoiZNmkiSnnzySZtxwzBksViUlpZmRiwAAACny3JTKjg4WFu2bFHv3r0VExMjwzAkSRaLRREREZo2bZqCg4OdFhQAACAn+uGHH8yOAAAAYIosN6UkqVSpUlq5cqXOnTunI0eOyDAMlStXToUKFXJWPgAAgBytQYMGZkcAAAAwhV1NqesKFSqkRx991NFZAAAAcp2NGzfednv9+vVdlAQAAMC17qopBQAAAMdo2LBhhjGLxWL9M2tKAQCAnCrLT98DAACA4507d87m59SpU1q1apUeffRRff/992bHAwAAcBrulAIAADCRr69vhrGnnnpKHh4eio6OVmxsrAmpAAAAnI87pQAAALKh4OBgHTx40OwYAAAATsOdUgAAACb65ZdfbF4bhqGTJ09qwoQJCgsLMycUAACAC9CUguMlxUtXzpidwnnO7jc7AQAgBwkLC5PFYpFhGDbjtWvX1qeffmpSKjjLyaQzOn/lotkxnOb3v4+bHQEAcB+hKQXHSoqX5lSQUv8xO4lzueeTvAPMTgEAyAHi4uJsXru5uSkwMFBeXl4mJYKznEw6o8hPB+lqarLZUZzKy91Tft4FzY4BALgP0JSCY105829DqtkXkn8Fs9M4j3eA5FPS7BQAgBygVKlSZkeAi5y/clFXU5M1rlmUyhQuZnYcp/HzLqgiPvzyDgBwZzSl4Bz+FaTgamanAAAg21q3bp2ioqK0bds2+fj42Gy7cOGC6tatq5kzZ+rxxx83KSGcpUzhYqoQHGp2DAAATMfT9wAAAEwwefJk9ejRI0NDSpJ8fX318ssva9KkSSYkAwAAcA2aUgAAACbYs2ePmjRpcsvtjRs3VmxsrAsTAQAAuBZNKQAAABMkJiYqb968t9zu7u6u06dPuzARAACAa9GUAgAAMEGxYsW0d+/eW27/5ZdfVKRIERcmAgAAcC2aUgAAACZo1qyZhg8frqtXr2bYduXKFY0cOVItWrQwIRkAAIBr8PQ9AAAAEwwbNkxLlizRgw8+qKioKD300EOSpAMHDmjatGlKS0vTG2+8YXJKAAAA56EpBQAAYILg4GBt2bJFvXv3VkxMjAzDkCRZLBZFRERo2rRpCg4ONjklAACA89CUAgAAMEmpUqW0cuVKnTt3TkeOHJFhGCpXrpwKFSpkdjQAAACnoykFAABgskKFCunRRx81OwYAAIBLsdA5AAAAAAAAXI6mFAAAAAAAAFyOphQAAAAAAABcjqYUAAAAAAAAXI6mFAAAAAAAAFyOphQAAAAAAABcjqYUAAAAAAAAXI6mFAAAAAAAAFwuWzelxo8fr0cffVQFCxZUUFCQIiMjdfDgQZs5V69eVZ8+fVS4cGEVKFBAbdq0UWJios2c+Ph4NW/eXPny5VNQUJBeffVVpaamuvJUAAAAXGbatGkqXbq0vLy8VKtWLe3YseOWc2fPnq3HH39chQoVUqFChRQeHn7b+QAAAI6SrZtSGzZsUJ8+fbRt2zatWbNG165dU+PGjXX58mXrnIEDB+o///mPvvrqK23YsEEnTpzQM888Y92elpam5s2bKyUlRVu2bNG8efM0d+5cjRgxwoxTAgAAcKpFixYpOjpaI0eO1M6dO1W1alVFRETo1KlTmc5fv3692rdvrx9++EFbt25ViRIl1LhxYx0/ftzFyQEAQG6TrZtSq1atUteuXfXwww+ratWqmjt3ruLj4xUbGytJunDhgj755BNNmjRJjRo1UvXq1TVnzhxt2bJF27ZtkyR9//33+u233/TFF18oLCxMTZs21dixYzVt2jSlpKSYeXoAAAAON2nSJPXo0UPdunVTxYoVNXPmTOXLl0+ffvpppvPnz5+vV155RWFhYSpfvrw+/vhjpaena+3atS5ODgAAcpts3ZS62YULFyRJ/v7+kqTY2Fhdu3ZN4eHh1jnly5dXyZIltXXrVknS1q1bVblyZQUHB1vnREREKCkpSfv27XNhegAAAOdKSUlRbGysTW3k5uam8PBwa210J//884+uXbtmrbcAAACcxd3sAFmVnp6uAQMGqF69eqpUqZIkKSEhQR4eHvLz87OZGxwcrISEBOucGxtS17df35aZ5ORkJScnW18nJSU56jQAAACc5syZM0pLS8u09jlw4ECW9jFkyBAVLVrUprF1I+okAADgKPfNnVJ9+vTR3r17tXDhQqcfa/z48fL19bX+lChRwunHBAAAMNuECRO0cOFCLV26VF5eXpnOoU4CAACOcl80paKiovTdd9/phx9+UPHixa3jISEhSklJ0fnz523mJyYmKiQkxDrn5qfxXX99fc7NYmJidOHCBevPn3/+6cCzAQAAcI6AgADlyZMn09rnVnXPde+++64mTJig77//XlWqVLnlPOokAADgKNm6KWUYhqKiorR06VKtW7dOoaGhNturV6+uvHnz2izEefDgQcXHx6tOnTqSpDp16ujXX3+1eeLMmjVr5OPjo4oVK2Z6XE9PT/n4+Nj8AAAAZHceHh6qXr26TW10fdHy67VRZiZOnKixY8dq1apVqlGjxm2PQZ0EAAAcJVuvKdWnTx8tWLBA3377rQoWLGhdA8rX11fe3t7y9fVV9+7dFR0dLX9/f/n4+Khv376qU6eOateuLUlq3LixKlasqE6dOmnixIlKSEjQsGHD1KdPH3l6epp5egAA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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from khisto import cumfreq\n", - "\n", - "# Cumulative counts\n", - "cumcount, cum_edges = cumfreq(data)\n", - "print(f\"Final cumulative count: {cumcount[-1]:.0f}\")\n", - "print(f\"Number of cumulative bins: {len(cumcount)}\")\n", - "\n", - "# Cumulative probabilities (CDF)\n", - "cdf, cdf_edges = cumfreq(data, density=True)\n", - "print(f\"Last CDF value: {cdf[-1]:.6f}\")\n", - "\n", - "fig, axes = plt.subplots(1, 2, figsize=(12, 4))\n", - "axes[0].stairs(cumcount, cum_edges, color=\"darkorange\")\n", - "axes[0].set_title(\"Adaptive cumulative counts\")\n", - "axes[0].set_xlabel(\"Value\")\n", - "axes[0].set_ylabel(\"Cumulative count\")\n", - "\n", - "axes[1].stairs(cdf, cdf_edges, color=\"seagreen\")\n", - "axes[1].set_title(\"Adaptive cumulative density\")\n", - "axes[1].set_xlabel(\"Value\")\n", - "axes[1].set_ylabel(\"Cumulative probability\")\n", - "axes[1].set_ylim(0, 1.05)\n", - "\n", - "plt.tight_layout()\n", - "plt.show()" - ] - }, { "cell_type": "markdown", "id": "1eba79b4", @@ -260,7 +196,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 7, "id": "b6c4ea8c", "metadata": {}, "outputs": [ @@ -298,7 +234,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 8, "id": "6c89bf07", "metadata": {}, "outputs": [ @@ -325,7 +261,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 9, "id": "25d8d0e5", "metadata": {}, "outputs": [ @@ -362,7 +298,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 10, "id": "d985437b", "metadata": {}, "outputs": [ @@ -446,7 +382,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 11, "id": "51179a02", "metadata": {}, "outputs": [ @@ -480,7 +416,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 12, "id": "e9bbabc9", "metadata": {}, "outputs": [ @@ -517,7 +453,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 13, "id": "1190f8aa", "metadata": {}, "outputs": [ @@ -553,7 +489,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 14, "id": "bf2ba150", "metadata": {}, "outputs": [ @@ -607,7 +543,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "khisto-python", "language": "python", "name": "python3" },