Skip to content

Instantly share code, notes, and snippets.

@bilzard
Last active November 23, 2022 08:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bilzard/ba58612ecc17dfb6ddd051503ce55f62 to your computer and use it in GitHub Desktop.
Save bilzard/ba58612ecc17dfb6ddd051503ce55f62 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": 121,
"id": "a42a1f8f-1029-4d5c-83ec-c226ee17a362",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"pandas: 1.5.2\n",
"polars: 0.14.31\n",
"1.39 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"852 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"1.43 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"1.2 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"1.58 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"2.16 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"1.82 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n",
"3.9 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": 122,
"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.385545</td>\n",
" <td>0.852120</td>\n",
" <td>1.625997</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2000000</td>\n",
" <td>1.426772</td>\n",
" <td>1.204987</td>\n",
" <td>1.184056</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>5000000</td>\n",
" <td>1.581371</td>\n",
" <td>2.162969</td>\n",
" <td>0.731111</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>10000000</td>\n",
" <td>1.820652</td>\n",
" <td>3.903561</td>\n",
" <td>0.466408</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"name n_groups pandas polars ratio\n",
"0 1000000 1.385545 0.852120 1.625997\n",
"1 2000000 1.426772 1.204987 1.184056\n",
"2 5000000 1.581371 2.162969 0.731111\n",
"3 10000000 1.820652 3.903561 0.466408"
]
},
"execution_count": 122,
"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": 123,
"id": "079cbacd-f91e-4940-b3a6-be74dbc1458d",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x7f05cf1eaec0>"
]
},
"execution_count": 123,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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fHyu+n1ptpSISCFlGLDtS/jxachKv8KJNnPW1BM7r2nMjTOzpdRzcxUlfbzZ82o3h8799fBJBk+7+iag0//ditbVyjn03s5o06ZNjkXvIiMjmTBhAna7nejoaEaPHs2OHTs4deoUWVlZgLmWUP369bNf07hx4+zPL+znlJCQQJUqVfj99995+OGHc7xnZGQkq1atym7Hx8fz8ssvExUVRUJCAna7nbNnzxITEwPAgAEDmDhxItWrV6d79+707NmT3r17U6KE/lMUESky0s/Cj0/BjplmO7wpxF7ohb+4z+T876Tu4wtsMDFozM1V2Ww2SvmWcOijfa3rCA/y53Jr6towZ021r3WdQ9dz1eq8qampdOvWjcDAQGbMmMHmzZtZsGABAOnpOdP2xb0pF97/QhByxKBBg4iOjub9999n/fr1REdHU758+ez3iYiIYN++fXz88ceULFmSRx99lJtuuknbK4iIFBXHD8DUzmawsXlB51Hw0Cq480sIvGRGcGBF87gL1rlxhv657ELeXjZG9a7PI19vw0ae2ZVRvevj7eWeLQU2bdqUo71x40Zq1arF3r17OXHiBOPHjyciIgIwH0s5q169emzatImBAwfmeI+LrVu3jo8//piePXsC5u7vx48fz3FOyZIl6d27N71792bYsGHUrVuXnTt35thEVURECqHdC+C7xyA9GUqHwB3/hWrtza/V72NO9z6y3hw8XCYUqrYt0B6bCxRuXKx7w3Am39c81zo3YQWwzk1MTAwjR47kP//5D9u2bePDDz9kwoQJVKlSBV9fXz788EMefvhhdu3axdixY52+/ogRIxg8eDAtW7akXbt2zJgxg927d+cYUFyrVq3smVlJSUk888wz2bt7A0yfPh273c4NN9xAqVKl+PrrrylZsiRVq1Z1yd+BiIi4QWY6LH8FNk0x21XbmcEmICzneV7e/4QdCyncuEH3huF0rR/Gr4dPkpCcSkiAP62rlXNbj80FAwcO5Ny5c7Ru3Rpvb29GjBjB0KFDsdlsTJ8+nRdffJEPPviA5s2b884779Cnj3PdhHfddRcHDx7k2WefJTU1ldtvv51HHnmEpUv/GXD9+eefM3ToUJo3b05ERARvvPEGTz/9dPbXg4ODGT9+PCNHjsRut9OoUSO+//57ypcv77K/BxERcaHTR2HOYPjrfI9/uyeg0yvgXXgj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0++lcCMibtO4ceMc7fDwcBISEq74mn379hEREZEdbABat26d57ktW7bM/jwpKYljx47Rrl27HOe0a9eOHTt2OFV3iRIlaNWqVXa7bt26BAcH8/vvv9O6dWtGjhzJgw8+yFdffUWXLl0YMGAANWrUcOo9RIqbZs2aYbfbSUhIuOoYmsOHD7Nq1SoWLVqUr/fSmBsRcZtLH9XYbDaysrJcdn2n177wMn/kGYaRfSw/A5FHjx7N7t276dWrFz///DP169dnwYIFTl9HxNOkpKQQHR1NdHQ0YIaU6OhoYmJiqF27Nvfeey8DBw5k/vz5HD58mF9//ZVx48bx448/5rjOf//7X8LDw+nRo0e+6lC4EZFCpU6dOhw9epT4+PjsY5s3b77q6wIDA6lYsWL2uJgL1q1bR/369QG47rrrAIiNjc3++oUfwhfLzMzMMUB43759nD59mnr16mUfq127Nk8++STLli2jf//+eQ6IFClutmzZQrNmzWjWrBkAI0eOpFmzZvzf//0fANOmTWPgwIE89dRT1KlTh379+rF582aqVKmSfY2srCymT5/O4MGDcz2+cpQeS4lIodK1a1dq1KjBoEGDeOutt0hOTubll18GzJ6fK3nmmWcYNWoUNWrUoGnTpkybNo3o6GhmzJgBQM2aNYmIiGD06NG8/vrr/O9//2PChAm5ruPj48Njjz3GBx98QIkSJRg+fDht2rShdevWnDt3jmeeeYY77riDatWq8eeff7J582Zuv/121/9liBQxHTt2zNEzeikfHx/GjBnDmDFjLnuOl5dXjtmJ+aFwIyKFire3NwsXLuTBBx+kVatWVK9enbfffpvevXvj7+9/xdc+/vjjJCYm8tRTT5GQkED9+vVZtGhR9oBfHx8fvvnmGx555BEaN25Mq1ateO2113KtflqqVCmee+457rnnHv766y/at2/P559/nl3fiRMnGDhwIPHx8VSoUIH+/ftf8Ye1iBQsm3GliCUiUgisW7eOG2+8kQMHDrh94O706dN54okncqyFIyJFi3puRKTQWbBgAWXKlKFWrVocOHCAESNG0K5dO81IEhGHaECxiBSoGTNmUKZMmTw/GjRoAEBycjLDhg2jbt26DB48mFatWvHdd99ZXLmIFBV6LCUiBSo5OTnHTKiL+fj4ULVq1QKuSEQ8jcKNiIiIeBQ9lhIRERGPonAjIiIiHkXhRkRERDyKwo2IiIh4FIUbERER8SgKNyIiIuJRFG5ERETEo/w/ziuzHNW5zL0AAAAASUVORK5CYII=\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()"
]
}
],
"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.10.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment