Skip to content

Instantly share code, notes, and snippets.

@bilzard
Created November 23, 2022 08:04
Show Gist options
  • Save bilzard/6f7ad80b6eb3a6011e7919a10824c37d to your computer and use it in GitHub Desktop.
Save bilzard/6f7ad80b6eb3a6011e7919a10824c37d to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "28b5fb06-b515-4c51-af50-728367d59556",
"metadata": {},
"outputs": [],
"source": [
"%load_ext lab_black"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "a42a1f8f-1029-4d5c-83ec-c226ee17a362",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"pandas: 1.3.5\n",
"polars: 0.14.29\n",
"1.64 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"846 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"1.73 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"1.19 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"1.89 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"2.18 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"2.25 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"3.76 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n"
]
}
],
"source": [
"from timeit import timeit\n",
"\n",
"import pandas as pd\n",
"import numpy as np\n",
"import polars as pl\n",
"import matplotlib.pyplot as plt\n",
"\n",
"print(\"pandas: \", pd.__version__)\n",
"print(\"polars: \", pl.__version__)\n",
"\n",
"N = 50_000_000\n",
"result = {}\n",
"for n_groups in [1_000_000, 2_000_000, 5_000_000, 10_000_000]:\n",
" df = (\n",
" pd.DataFrame(\n",
" {\n",
" \"a\": np.random.randint(0, n_groups, N).astype(\"uint32\"),\n",
" \"b\": np.random.randint(0, n_groups * 20, N).astype(\"uint32\"),\n",
" }\n",
" )\n",
" .sort_values(\"a\")\n",
" .reset_index(drop=True)\n",
" )\n",
" result[(\"pandas\", N, n_groups)] = %timeit -o -r 1 pd.concat([df[\"b\"], df.groupby(\"a\")[\"b\"].shift(-1).rename(\"b_next\")], axis=1).dropna()\n",
" pl_df = pl.from_pandas(df)\n",
" result[(\"polars\", N, n_groups)] = %timeit -o -r 1 pl_df.groupby(\"a\").agg([pl.col(\"b\"), pl.col(\"b\").shift(-1).alias(\"b_next\")]).explode([\"b\", \"b_next\"]).drop_nulls()[[\"b\", \"b_next\"]]"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "dd7e71e0-27ba-4a32-a324-0db44ec369fa",
"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>name</th>\n",
" <th>n_groups</th>\n",
" <th>pandas</th>\n",
" <th>polars</th>\n",
" <th>ratio</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1000000</td>\n",
" <td>1.641448</td>\n",
" <td>0.845856</td>\n",
" <td>1.940576</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2000000</td>\n",
" <td>1.733902</td>\n",
" <td>1.187401</td>\n",
" <td>1.460250</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>5000000</td>\n",
" <td>1.892741</td>\n",
" <td>2.183766</td>\n",
" <td>0.866733</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>10000000</td>\n",
" <td>2.248044</td>\n",
" <td>3.763220</td>\n",
" <td>0.597372</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"name n_groups pandas polars ratio\n",
"0 1000000 1.641448 0.845856 1.940576\n",
"1 2000000 1.733902 1.187401 1.460250\n",
"2 5000000 1.892741 2.183766 0.866733\n",
"3 10000000 2.248044 3.763220 0.597372"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data = []\n",
"\n",
"for (name, N, n_groups), ret in result.items():\n",
" data.append(dict(name=name, N=N, n_groups=n_groups, best=ret.best))\n",
"\n",
"\n",
"performance = (\n",
" pd.DataFrame(data)\n",
" .pivot_table(index=\"n_groups\", columns=\"name\", values=\"best\")\n",
" .reset_index()\n",
")\n",
"performance[\"ratio\"] = performance[\"pandas\"] / performance[\"polars\"]\n",
"performance"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "079cbacd-f91e-4940-b3a6-be74dbc1458d",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x7f540924dc70>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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OtHR0Xh4nHtWTbW7cuPh4UG9evVcXUaVEBISor8oKhG9H5WL3o/KR+9J5eKM9+N8V2wKaUKxiIiIuBWFGxEREXErCjdSiq+vL+PHj8fX19fVpQh6PyobvR+Vj96TyqUyvB/VbkKxiIiIuDdduRERERG3onAjIiIibkXhRkRERNyKwo2IiIi4FYWbaurtt9+mUaNG+Pn50aFDB37++eeznvvVV1/Rp08f6tSpQ0hICF27duW7776rwGrdnz3vR3GrV6/Gy8uLtm3bOrfAasbe9yM3N5dnn32WBg0a4OvrS5MmTZg9e3YFVev+7H0/Pv74Y9q0aUNAQABRUVHcfffdHDt2rIKqdW8rV65k0KBBREdHY7FYWLRo0Xkfs2LFCjp06ICfnx+NGzdm5syZzi/UkGrns88+M7y9vY333nvPSExMNB599FEjMDDQ2LNnT5nnP/roo8ZLL71k/Pbbb8aff/5pPP3004a3t7excePGCq7cPdn7fhQ6efKk0bhxY6Nv375GmzZtKqbYauBC3o/Bgwcbl19+ufH9998bSUlJxtq1a43Vq1dXYNXuy9734+effzY8PDyM119/3fj777+Nn3/+2WjVqpVxww03VHDl7mnJkiXGs88+ayxYsMAAjIULF57z/L///tsICAgwHn30USMxMdF47733DG9vb2P+/PlOrVPhphrq3LmzMXLkyBLHWrZsaTz11FPlfo7Y2Fhj4sSJji6tWrrQ9+PWW281nnvuOWP8+PEKNw5k7/vx7bffGqGhocaxY8cqorxqx9734+WXXzYaN25c4tj06dONevXqOa3G6qo84ebJJ580WrZsWeLYAw88YHTp0sWJlRmGbktVM3l5eWzYsIG+ffuWON63b19++eWXcj2HzWYjPT2dmjVrOqPEauVC3485c+awa9cuxo8f7+wSq5ULeT/i4uLo2LEj//3vf6lbty7Nmzdn7NixZGdnV0TJbu1C3o9u3bqxf/9+lixZgmEYHD58mPnz53PttddWRMlyhjVr1pR6//r168f69evJz8932utWu40zq7ujR49itVqJiIgocTwiIoJDhw6V6zmmTp1KZmYmt9xyizNKrFYu5P3YuXMnTz31FD///DNeXvpf2JEu5P34+++/WbVqFX5+fixcuJCjR4/y0EMPcfz4cc27uUgX8n5069aNjz/+mFtvvZWcnBwKCgoY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\n",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"_, ax = plt.subplots()\n",
"ax.plot(performance[\"n_groups\"], performance[\"pandas\"], marker=\"o\", label=\"pandas\")\n",
"ax.plot(performance[\"n_groups\"], performance[\"polars\"], marker=\"o\", label=\"polars\")\n",
"ax.set(xlabel=\"n_groups\", ylabel=\"Execution time [sec]\")\n",
"ax.legend()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "04df146b-6a38-46f8-8955-6e99e616ae15",
"metadata": {},
"outputs": [],
"source": []
}
],
"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.9.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment