{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Ibis 1.3 was just released, after 8 months of development work, with 104 new commits from 16 unique contributors. What is new? In this blog post we will discuss some important features in this new version!\n", "\n", "First, if you are new to the Ibis framework world, you can check this [blog post](https://labs.quansight.org/blog/2019/07/ibis-python-data-analysis-productivity-framework/) I wrote last year, with some introductory information about it.\n", "\n", "Some highlighted features of this new version are:\n", "\n", "\n", "* Addition of a `PySpark` backend\n", "* Improvement of geospatial support\n", "* Addition of `JSON`, `JSONB` and `UUID` data types\n", "* Initial support for `Python 3.8` added and support for `Python 3.5` dropped\n", "* Added new backends and geospatial methods to the documentation\n", "* Renamed the `mapd` backend to `omniscidb`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- TEASER_END -->" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "This blog post is divided into different sections:\n", "\n", "* OmniSciDB\n", "* PostgreSQL\n", "* PySpark\n", "* Geospatial support\n", "* Python versions support" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import ibis\n", "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### OmniSciDB\n", "\n", "The `mapd` backend is now named `omniscidb`!\n", "\n", "An important feature of `omniscidb` is that now you can define if the connection is `IPC` (Inter-Process Communication), and you can also specify the `GPU` device ID you want to use (if you have a NVIDIA card, supported by `cudf`).\n", "\n", "`IPC` is used to provide shared data support between processes. OmniSciDB uses Apache Arrow to provide IPC support." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['diamonds', 'batting', 'awards_players', 'functional_alltypes', 'geo']" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "con_omni = ibis.omniscidb.connect(\n", " host='localhost', \n", " port='6274',\n", " user='admin',\n", " password='HyperInteractive',\n", " database='ibis_testing',\n", " ipc=False,\n", " gpu_device=None\n", ")\n", "con_omni.list_tables()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Also you can now specify `ipc` or `gpu_device` directly to the `execute` method:" ] }, { "cell_type": "code", "execution_count": 3, "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>id</th>\n", " <th>bool_col</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>6690</td>\n", " <td>True</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>6691</td>\n", " <td>False</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>6692</td>\n", " <td>True</td>\n", " </tr>\n", " <tr>\n", " <th>3</th>\n", " <td>6693</td>\n", " <td>False</td>\n", " </tr>\n", " <tr>\n", " <th>4</th>\n", " <td>6694</td>\n", " <td>True</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " id bool_col\n", "0 6690 True\n", "1 6691 False\n", "2 6692 True\n", "3 6693 False\n", "4 6694 True" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = con_omni.table('functional_alltypes')\n", "expr = t[['id', 'bool_col']].head(5)\n", "df = expr.execute(ipc=False, gpu_device=None)\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can imagine, the result of `df` is a `pandas.DataFrame` " ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "pandas.core.frame.DataFrame" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(df)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But if you are using `gpu_device` the result would be a `cudf` :)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<small>\n", " \n", "> Note: when `IPC=True` is used, the code needs to be executed on the same machine where the database is running\n", ">\n", "> Note: when `gpu_device` is used, 1) it uses IPC (see the note above) and 2) it needs a NVIDIA card supported by `cudf`.\n", "\n", "\n", "Another interesting feature is that now `omniscidb` also supports `shapefiles` (input) and `geopandas` (output)!\n", "\n", "Check out the _Geospatial support_ section below to see more details!\n", "\n", "Also the new version adds translations for more window operations for the `omniscidb` backend, such as: \n", "`DenseRank`, `RowNumber`, `MinRank`, `Count`, [`PercentRank/CumeDist`](https://github.com/ibis-project/ibis/issues/1975).\n", "\n", "For more information about window operations, check the \n", "[Window functions](https://docs.ibis-project.org/sql.html#window-functions)\n", "documentation section." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### PostgreSQL\n", "\n", "Some of the highlighted features for the `PostgreSQL` backend are new data types included, such as:\n", "`JSON`, `JSONB` and `UUID`." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhUAAACbCAYAAADVwWn/AAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nO3dd1gU1/4/8Pcsu9IRu0YUK4olgiXYW7y2a40Uk4ii5ibxMdGUL6KxRo2aEI3RJN5oFCyQIHrtolGDGBULCkSsNxEVVAQLClJc4Pz+8Ld73eyCrAwO5f16nn3Emc+c/ezAnv3smTMzkhBCgIiIiKiEVEonQERERBUDiwoiIiKSBYsKIiIikoVa6QSIdKKjo5GUlKR0GkRlUteuXeHk5KR0GkRFkjhRk8oKLy8vbNmyRek0iMqksLAweHt7K50GUZE4UkFliqenJ8LDw5VOg6hMkSRJ6RSIioVzKoiIiEgWLCqIiIhIFiwqiIiISBYsKoiIiEgWLCqIiIhIFiwqiIiISBYsKoiIiEgWLCqIiIhIFiwqiIiISBYsKoiIiEgWLCqIiIhIFiwqiIiISBYsKqhcW758OSRJKvIRFxendJoAgISEBJP5bd++XenUZBETEwNJkjBv3jzFcpg1a5bBvq1Zs6ZiuRBVRiwqiIiISBYsKqjC2LVrF4QQRg83NzelUwMAtGnTRp/TqlWrlE6nQlq4cKF+H3t4eCidDlGlw6KCiIiIZMGigiqV8PBwtGnTBlZWVmjRogVCQ0MxevRo/TH4zMxMAIbH5mNiYvTbN2rUCJIkoWXLlgbtRkREwMfHBy1btoS1tTVsbW3h6uoKf39/pKenv3C+iYmJeP/999G0aVPY2NigQYMGGDJkiH5UpqzauXOnfl+4u7tj27ZtRjE5OTmYPXs2mjdvDktLS9SoUQPDhw9HfHx8iWLNFRQUBA8PD9jZ2cHW1hY9e/bEwYMHjeJiYmIwceJEuLi4wNLSEjVr1sSQIUMQGRlpEBcXFwdJkjBr1iycPn0aXbt2hbW1NZo2bYqQkJAS50tUpgmiMsLT01N4enqatc0333wjAAgAYteuXUXG7tmzR0iSpI8HICRJEg0bNtT/PyMjQwghxMyZM/XLTp8+rW/D2dlZABAtWrTQL7t9+7ZBm39/9OvXzyiXVatW6ddv27bNZL5paWmiVq1ahbYbGxtr1r4qrrS0tBfa7vTp0wKAGD58uFCr1Ub7OTw8XB9bUFAg+vfvb/J12djYiLNnz75Q7LM8PDxEjRo1isx54sSJJttVqVRi+/btBrGF/R5UKpXYt2+fPi42NlYAEOPHjxdVq1Y1in2R3xsAERYWZvZ2RC8bRyqowhg6dKjRmRV+fn769Z9//rn+2/2aNWvw4MEDzJkzBzdu3CjR80qShH79+mHTpk24cOECsrKykJKSghEjRgAADh48iOvXr5vd7v79+5GWlgYA+Prrr/H48WOkpaXht99+w6hRo2BhYVGivE3Jzc2Fu7s7li1b9sJt7NixAwEBAUhJScGdO3cwd+5cCCHg7++PgoICAMDu3bvx66+/om7dutizZw8yMjLw559/wtvbG1lZWQgICNC3Z06sOXbu3Im1a9eiWbNm2Lt3Lx4+fIgHDx4gLCwMtra2mDJlij5fAOjUqROCg4Nx8+ZNaLVapKenY8eOHVCpVFi5cqVR+5s2bcIHH3yAO3fuIDU1Fb6+vigoKOBoBVVsSlc1RDolHakw9Rg3bpwQQoiMjAz9KEXnzp312+fn54sGDRqUaKSioKBArF27VvTq1UvUqFFDWFhYGOURGRlpkHdxRip27dqljxk7dqy4cuWKWfvmRR06dEjY2NiIZcuWmbWdbqTi2f2r0717dwFAnD9/XgghxKRJkwQAERwcbBCXnZ0t6tatK9RqtcjKyjI79lnPG6nw9PQUAERcXJzRutmzZwsAIj4+Xr/s/Pnz4q233hJOTk5GIzFubm76ON1Ixd/3Q0pKigAghgwZUmhOhQFHKqic4EgFVRimzv4IDg4GANy+fVs/StGuXTv9NiqVCm3bti3R806fPh0TJ05EVFQU7t27h/z8fKOYnJwcs9sdMGAAunTpAgDYsGEDXFxcUL9+fbz99tuIiooyuz0nJydYWVk99zF48GDk5OTgk08+wYEDB8x+ns6dOxst052JoRsV0v3brVs3gzgrKyu0b98eeXl5uHXrltmx5rh8+TIAoEOHDlCr1bCwsIBKpYJKpcKCBQsAAMnJyQCACxcuwMPDA6GhoUhOTkZeXp5BW1qtttDXrFOnTh1UqVJFP2+HqCJSK50AkdKEGRMe/x6bm5urH/rWaDRYu3YtBg8ejGrVqiEwMBDTp0832Y4kSc99Lo1GgyNHjiAkJAS7d+9GdHQ0bt68idDQUPz8889Yv349fH19i527n59fsT7QhBBYt24dqlatiubNmxe7/eLQvW7dfizOfjAn1hy6dk0VgTpPnjwB8PQia5mZmZg0aRKmTJkCZ2dnWFtbAwCqVatmcls7OzujZZIklekJtkQlxaKCKoV69erpO/RnzxgoKChAQkKCUbxGo9H/nJWVBeDpt9HU1FSDuAcPHiA7OxsA0KpVK4MP+bNnzxaaj5WVlUEbhVGr1Rg3bhzGjRsHADh37hyGDx+OxMRELF++3KyiYuHChc+NEUJg4sSJcHBwQGRkJBo1alTs9nVOnDhhtOzkyZMAAGdnZ4N/jx07hqZNm+rjcnNzERsbC7VajVdeecXs2Gc5OjoiIyMDBQUFUKmMB2VbtGiBixcvIi0trdDCQOfq1auwsLDAihUroFb/r9s8ffo00tPTUb9+/SK3J6osePiDKgU7Ozt07NgRwNMPvZ9++gnp6emYP38+kpKSjOKdnJz0P4eFhSEzMxOBgYFGhzHq1Kmj/0Z65coVREdHIyMjA0FBQdi6dWuh+Tz74RgcHGxUrABAdHQ0hg0bhh07duD69evQarWwsrJClSpVAAAPHz40Yw8UT15eHjQaDQ4fPvzCoxQnTpzArFmzkJqairS0NCxYsABHjx5F48aN0aJFCwDAoEGDADw9dBQREYHMzEwkJiZi/PjxuH37Nnr16qUfCTAn9lnNmjXDkydPsHTpUuTm5hqtHzNmDPLz8zFkyBAcOnQI9+/fR3Z2NhISErB8+XL06tVLH9uwYUPk5+dj6dKlSE9Px8OHD7F79274+PgYFKBElZ4SEzmITCmNiZp45tTLXbt2mTyl1MnJyWii5q1bt4SVlZVBrLW1tXBwcDCaqDl9+nSTz1u7dm39zxEREQZ55+XliSZNmpjc7uLFi0IIIX7//fciX1dAQEBJdrfsdBM1R4wYYfKU0i1btuhjizpN1Nra2mByrDmxz4qPjzf6fb/33nsGMRMmTCh0/z47yfP48eNCpVIZxYwfP17Ur19ftG7dWh+rm6g5c+ZMo5wsLS1Fr169zN634ERNKic4UkGVxpAhQ7B582a0bdsWVapUQZMmTbBhwwajCYDA08Ml27ZtQ9u2bWFlZYXWrVsjPDzc5DD5ggULEBgYCFdXV1hbW8PZ2Rnz58/HjBkzCs3FwsICe/fuxeDBg2Fvb28ypmvXrti3bx/efvttuLi4wMrKCjY2NnBzc0NgYCC++OKLF98Zpahdu3bYvHkzmjVrBktLS7i7u2PLli0YNWqUPkZ3I7WZM2eiadOm0Gg0cHR0xNChQ3H06FH9qJK5sc969dVXsXHjRjRt2rTQ+Rhr167Fxo0b0bNnTzg4OMDa2hqtW7fGlClTDCbDdunSBbt27UKnTp1ga2uLevXqwd/fHz/++KNMe42oYpCE4KwhKhu8vLwAPL3q5cs0evRohIWFAQAyMjJMTrAjUpIkSQgLC4O3t7fSqRAViSMVREREJAsWFURERCQLFhVEREQkCxYVVOn98ssv+itwcj4FEdGLY1FBREREsmBRQURERLJgUUFERESyYFFBREREsmBRQURERLJgUUFERESyYFFBREREsmBRQURERLJgUUFERESyYFFBREREsmBRQURERLJgUUFERESyYFFBREREsmBRQURERLJQK50A0bOSk5OxefNmpdNQjFarxYULF2Bra4tmzZopnY7i/vzzT2RlZcHV1RUajUbpdIjoOVhUUJly4sQJ+Pj4KJ0GERG9AEkIIZROgqgyyc7OxpEjRxAREYGdO3ciMTERarUaeXl5UKvVOHXqFNzd3ZVOs8yIjY2Fh4cHtFotLCwskJ+fj1deeQXDhg3DgAED8Prrr8Pe3l7pNIkILCqIXoqrV6/i4MGD2L9/P/bt24esrCxoNBpotVp9jEqlwpdffon/+7//UzDTsmnZsmXw9/dHQUGBflmVKlWg1WohSRLatGmDkSNHYujQoXB3d4dKxeliREpgUUFUCnJycnD06FEcPHgQe/bsQUJCAiwsLCCEMPhg1NFoNPDw8EBUVBQ/EE0QQmDw4ME4dOiQQSGmI0kSNBoNnjx5gqpVq6Jfv37o378/hg4dinr16imQMVHlxKKCqBRs27YNb7zxhv6wRlFUKhXs7e1x/vx51K9f/yVlWP7cuXMHrVq1Qnp6usnC7FkqlQoFBQXYuXMnhg4d+pIyJCJ+JSIqBSNHjoSfnx8kSXpubEFBAYKCglhQPEedOnUQGhqK4nwPUqlUePfdd1lQEL1kHKkgKiWPHz9G27ZtkZSUVOhohVqtxvjx47F69eqXnF35NXXqVHz//ffIz883ud7CwgL169dHQkICJ3ASvWQsKohKUUxMDDp37mzyA1CtVus//Ozs7BTIrnzKzc1Fx44dcfnyZZPzK1QqFY4dO4bOnTsrkB1R5cbDH0SlRAiBEydOwMbGxuTkSyEENm/ezILCTJaWlggLCzO5Ty0sLFC1alXs3bvXZMFBRKWLRQVRKUhNTcWwYcPw8ccf4/3334e7uzvU6v9da06lUmHRokV47bXXFMyy/GrVqhWWL19uMGdFo9GgdevW+OKLL7Bs2TJ069YNly9fVjBLosqHhz+IZLZ//36MHz8elpaW2LhxI7p3746rV6+iTZs2yM7OhlqtRteuXREZGcnTR0to+PDhiIiIgFarhZWVFeLj4+Hi4oJLly7B19cX58+fx+LFizFlypRiTZolopJhj0Ykk+zsbEydOhWDBg1Cv3798Mcff6B79+4AgCZNmuCHH34AANjY2CA0NJQFhQzWrVuH6tWrAwC++eYbuLi4AABatmyJ6OhozJ07F/7+/hg4cCBu3bqlZKpElQJHKohkEBMTgzFjxuDOnTv44Ycf8Oabb5qM8/LywujRozFq1KiXnGHFdeTIEXz55ZfYvXu3ydGIkydPwtfXFw8ePMDq1asxcuRIBbIkqhxYVBCVQEFBAVauXIlp06ahR48eWL9+fZHXm8jNzYWlpeVLzLBy0Gq1Rd7FNCsrCzNmzMCKFSvg5eWF1atXw9HR8SVmSFQ5sKggekHXr1/H2LFjcerUKcybNw/+/v48pFHGRUREYOLEibC0tMT69evRs2dPpVMiqlDYAxK9gPDwcLi7u+Pu3buIjo5GQEAAC4pyYNCgQYiLi0Pbtm3Rp08fTJ06FU+ePFE6LaIKg70gkRkePnwIX19f+Pj4wMvLC6dPn4abm5vSaZEZateujZ07dyIoKAjr1q1Dx44d8ccffyidFlGFwKKCqJiOHz+O9u3b48CBA9i9ezd+/PFH2NjYKJ0WvaCxY8fijz/+gIODAzw8PPDll18+90ZlRFQ0FhVEz6HVajFv3jz07NkTbm5uOH/+PAYPHqx0WiSDxo0b4/Dhw5g3bx5mz56NgQMH4ubNm0qnRVRucaImUREuXryIMWPG4NKlS1i0aBGmTp2qdEpUSk6dOgVfX1+kpqbi+++/x1tvvaV0SkTlDkcqiEwQQmD16tXo1KkT1Go14uLiWFBUcK+99hri4uIwduxYjBkzBt7e3njw4IHSaRGVKxypIPqb1NRUvPPOO4iIiMCnn36KBQsWFHkNBKp49u3bhwkTJqBKlSpYv349evXqpXRKROUCRyqInrF//364ubnh3LlziIyMxJIlS1hQVEIDBw5EfHw83NzceOopkRlYVBCh6Pt2UOVUq1YtbN++HcHBwVi3bh06dOiA+Ph4pdMiKtNYVFClFxMTA3d3d2zYsAEhISHYsGED7O3tlU6LygjdqaeOjo7o3LkzTz0lKgKLCqq0CgoK8O2336Jbt25wcnJCQkJCoTcCo8qtcePGiIyM1J96OmDAACQnJyudFlGZw6KCKqUbN26gT58+CAgIwPz58/Hrr78WeSMwIrVajYCAABw7dgxJSUlo06YNQkJClE6LqExhUUGVTnh4ONzc3HD37l2cOHGC9+0gs3Tq1AmxsbEYN24cfH19eeop0TPYk1Klwft2kFysra3x7bffIiIiAseOHYObmxsOHz6sdFpEimNRQZUC79tBpWHAgAGIi4tD+/bt0bdvX0ydOhW5ublKp0WkGBYVVKHxvh1U2mrVqoVt27YhODgYQUFB6NChA+Li4pROi0gRLCqowrp06RI6d+6MwMBALF26FFu3bkWNGjWUTosqKN2pp9WrV0eXLl146ilVSiwqqMLR3bejY8eOvG8HvVSNGjXSn3o6Z84c9O/fH0lJSUqnRfTSsKigCiU1NRXDhw/H5MmT8cEHH+Do0aNo3ry50mlRJWJhYaE/9TQ5ORlt27bFxo0blU6L6KVgUUEVBu/bQWVJx44d9aeejhs3Dt7e3rh//77SaRGVKhYVVO7xvh1UVulOPd23bx+OHz8ONzc3REZGKp0WUalhUUHlGu/bQeVB//79kZCQgO7du+P111/nqadUYbGooHKJ9+2g8sbR0RGhoaEICwvDhg0b0KFDB8TGxiqdFpGsWFRQuXPjxg307duX9+2gcsnLywtxcXGoUaMGPDw8MG/ePJ56ShUGiwoqV3T37UhLS+N9O6jccnZ2RmRkJAIDA7F48WL06NEDV69eVTotohJjb0zlAu/bQRWNSqXC1KlTERMTg8zMTLi7u2P16tVKp0VUIiwqqMzjfTuoImvbti1OnjyJSZMmYdKkSTz1lMo1FhVUZvG+HVRZWFlZYcmSJdi/fz+OHz+O1q1bY+/evUqnRWQ2FhVUJvG+HVQZ9evXDwkJCejbty+GDBmC9957D1lZWUqnRVRsLCqoTOF9O6iyc3R0REhICMLCwhAeHo5OnTrx1FMqN1hUUJnB+3YQ/Y+XlxdiY2NRq1Yt/amn+fn5SqdFVCRJCCGUToJo//79GD9+PCwtLbFx40ZeZpvo/xNCYMWKFQgICED79u2xceNGNG3aVOm0iEwyKiqSk5Nx/PhxpfKhSmjv3r1Yv349evfuDT8/P1hbWyudUoXj7e1dKu2yv3h5rl27hpUrV+L+/ftYuHAhL/hGimvQoAG6dOliuFD8TVhYmADABx98VKBHaWF/wQcflffh6elp1CeoUQgeFSEq/zZv3gwfH59Sfx72F0SVi5eXl8nlnKhJREREsmBRQURERLJgUUFERESyYFFBREREsmBRQURERLJgUUFERESyYFFBREREsmBRQURERLJgUUFERESyYFFBREREsmBRQURERLJgUVGG7Nu3D5IkQZIkLF++XOl0iKiCYN9CL4usRUXt2rX1f7iSJOGNN96Qs3kAQGZmJqZNm4YmTZpAo9FAkiQsXrxY9ucpqbp160KSJLRp00bpVBSRkJBg8Lege2zfvl3p1BRnZWWF3r17m7VNZmYmJEmCp6dn6SRVjvzyyy+QJAmbNm0qcVtz5syBJEk4ffq0DJm9HOxb2LcUpiz0LbIVFY8fP0ZaWprBMqP7rMtg4sSJCAwMRGJiIvLy8gAAzZo1M4obNWoULCwskJWVJXsOStu+fbv+jfTvf/9b6XSIXipdAfDaa6+VuK0zZ85AkiS0atWq2NuwbyEqnGxFha2tLYQQEEJg27ZtAOQvKq5fv47w8HB06tQJiYmJKCgogBDC5C1YY2Nj4eLiAhsbG1lzKE0DBw7U78OPPvpI6XRKpE2bNvrXsmrVKqXTKVNycnJw+PBhpdMot5YuXQohBFxcXErc1pkzZ9CoUSPY2toWexv2Lcpi31K4stC3lMqciiNHjkCj0aBDhw6ytnvgwAEIIRAQEIBGjRpBkiSTcenp6UhMTISbm5usz09EFUdycjLu3Llj1mEE9i1ERSuVoiIqKgpubm6wtrYuNCYzMxPz58+Hq6srLC0t8corr+Djjz9Gdna2QVxoaKh+OO5f//oXAMDT01O/bMSIEQCAvLw8qNVqSJKEatWqAfjfsVfdIyQkxGQuS5YsgSRJaNSokQyv3nx2dnZGxwdNTaaysrKCJEkYOXKkftmkSZP029jZ2RnEP3r0CJ999hlatGgBKysrODg4oGfPnti8ebNR27t379a3891332H16tVo1aoVrKys0L17d1y8eFEfGxERAR8fH7Rs2RLW1tawtbWFq6sr/P39kZ6eLuOeebni4uIgSRJmzZpltO7vxyrNiQUAPz8/g99vUcc9U1NT4efnh5o1a8LBwQHjx483el9UBPfv34ckSfD29sbjx48xbdo0NGjQALa2tpgwYYLB4YW+ffsa7L8PP/yw0Hb/+usvvPnmm6hevTpq166Nr776Cn/99ZfR7ysmJgbA02++x48fh4eHB2xtbdGxY0dER0fr49i3sG8pqcrUt6hlbQ1P/9ji4+MxefLkQmNu3ryJfv364dKlS/plt2/fxvLly/Hf//4Xu3fv1i9PTEws8vkaNmwI4Om3jvz8/CJjlXpjKyE9PR3dunXDhQsX9Mtyc3Px+++/4/fff8e5c+ewYMECk9uuW7cOsbGx+v8fO3YMs2fPxpYtW5CSkoLBgwcbbXPp0iVcunQJcXFxOHDggPwvyAx3795FzZo1Fc3hRWVnZ6N3794GHW1wcDAyMzMVzKp06D7UGzRogCFDhhgM2wYFBeGdd95B165dARj3A4UdWo2JiUHfvn2RkZGhXxYQEICrV68CMJyHcebMGQBARkYGXn/9deTk5OiXjxo1CklJSbCwsGDf8jfsW9i3FEX2kYqjR48iPz+/0De9VqvFkCFDcOXKFXz66ae4dOkScnJycPnyZQwYMAB79uzBqVOn9PEzZ87UHz+rX7++wfE0IQRWrFgB4OmbWrfs008/BfB0lvCzsd26dZP75coiMzMTQghEREQUGZeTk2MwZwUAVq1apX99z/5xfPbZZ/o3/dKlS/Ho0SNcv35d/6b94osvkJCQYPJ5YmNjMWHCBCQmJiIjIwNfffWV/lCTJEno168fNm3ahAsXLiArKwspKSn6EaODBw/i+vXrL74zSig3Nxfu7u5YtmyZYjmYEhwcrP89WVpaFhq3Zs0aXLx4Ee3atUNMTAwyMzMRGRlZrs5OKC7dh/q+ffug1Wpx+PBhPHz4EJcvX4afn5/B5MnExEQIIfDDDz8AADp37mzUXnZ2Nry8vJCRkYEZM2bg1q1bePToEebNm4c1a9YAMCwqdEXNrl27EBISgocPH+LKlSto3rw5bt++jRs3bgBg38K+5Sn2LcUje1ERFRUFoPBvEj/++CPi4uKwcuVKfP3112jRogUsLS3h4uKC6dOnA/jfm/1ZSUlJuHnzZrEmfx4+fBi1a9dG69ati5Xz9OnTIYTAtWvXihVf1hUUFCA0NBTA0873k08+gb29PRo2bIivvvoKACCEwH/+8x+T27dv3x4//fQTGjVqBDs7O/j7++Odd94B8PS04TfffBNr1qxBjx49YG9vj7p16xqczvW80aXSZGlpifXr12P27Nn45ptvFMvjRek6/zVr1qBDhw6wtbVF79698fXXXyucmfx07/M6deogKioKvXr1goODA1xcXBAUFARHR0ejbXTv7SZNmhitCw4OxrVr1zB16lQsWrQI9erVg729PebOnQs7Ozs0aNAAdevW1cfrzvwICwvDG2+8AQcHBzRv3hx9+vQBAJMTMdm3sG9h31I02Q9/HDlyBPXq1YOzs7PJ9UFBQQCAyZMnF3qIRAhhtEx3jNPUN5RnPXr0CHFxcRg1apQ5aVcoKSkpePjwIQDg5MmTUKvVBt+qdAp7g/7zn/80mgQ7YMAAAE87SV3nURjdMLLcnJyccPfu3WLFarVafPLJJ2jTpg3+8Y9/lEo+pSEpKQlqtRrt27c3WP68v/vySFdUrF69GhYWFsXa5siRI4Xui7CwMKjVasyePdtgeUFBAfLy8gxGKZKSkpCWloYePXrAw8PDIP7ChQuoVq0a6tSpY7CcfQv7FoB9y/PIWlRkZWXhzJkzGDp0qMn1Wq3W4HhaYerXr2+07MSJEwCef5rqkSNHkJ+fb/YFQCqSZ9/cQohCjwcXNkGnsGOGubm5WLlyJQBAo9Fg7dq1GDx4MKpVq4bAwED9SNPfFXaWjrn8/PyKdfxPCIF169ahatWqaN68ebHb1+X596L2yZMnePLkyQvHkrG7d+/ixo0b8PDwMHmdGVMuXryIlJSUIudTNG7cGDVq1DBYHhUVhaysLJOHPnQfaDparRYxMTEm+w/2Lexb2Lc8n6xFxblz56DVauHu7m5yfUZGBoQQGDZsGHbs2GFW29HR0XB0dETLli2LjDt+/DgAoFevXma1X548+0YyNapTp04d2NnZITMzE/369TN7cpNKZfqo2IMHD/SdRatWreDr66tfd/bs2ULbs7KyMmjjRS1cuPC5MUIITJw4EQ4ODoiMjDRrAp3uWgXJyckGy0+fPm20n82JNYezszPOnz+Ps2fPolOnTvrluqK6otB9qPft27fY2+gmcpr6ZqXVavH48WOT15vQ/d2YmqT59wIlNjYWOTk5JgsX9i3sW9i3PJ+scyp0v9QTJ07g3r17RuurVauGGjVq4LfffkNISAju3buH3NxcXLlyBSEhIRg4cCAuX75stN2TJ08QGxsLDw+P51amumOX169f119x83mUPu3LXLrT2oCn354eP35ssF6tVusvuXro0CEsWrQIN2/eRG5uLq5du4adO3fCy8vL7Ak6ug4FAK5cuYLo6GhkZGQgKCgIW7duLXS7pk2b6n8ODg5GamqqWc9rjry8PGg0Ghw+fNisbxLA0zedtbU1tm7digMHDiArKwsxMUCYsywAAARiSURBVDH48MMPjTpDc2LNMWjQIADAe++9h9jYWDx+/BhRUVHw9/d/4TbLIt2HujkTHKOiomBhYWHQIepoNBrUqVMH8fHxWLduHbKysnD9+nVMnDgRkZGRUKlU6Nixoz4+JiYGFhYWRlflLGpElH0L+xb2LcUg/iYsLEyYWFwsSUlJQqPRCAD6h0ajEXl5efqYJUuWGKx/9qFWq8WTJ0+M2o2OjhYAxNy5c5+bw4wZM4zafffdd4vcZvHixQKAcHZ2NvclF6pOnTqFvk4AYtSoUUIIIUaNGlVkHADRrl07g7YzMjJE1apVjeJsbW31MampqcLFxaXIdqOjo/Xxu3bt0i9fuXJloa9r+vTpJtuqXbu2/ueIiAiDbfLy8kSTJk1Mbnfx4kU5drdsxo4da5Tj5MmThaWlpejVq9cLxf7888/P/R0nJiYKIYTIysoSrq6uRuu9vb0N/m6KqyTv59Jsf8SIEUKSJHHv3r1CY6Kiop6736KiovTx06ZNM1rfuXNn4eTkJFq3bm3Qdq1atYzeV0IIMXr0aKFSqUR6errROvYtT7FveTEVrW/x9PQUnp6eRstlHalwcnJCaGgoXn31Vf2Frxo3bmwwCSsgIAC//PILunbtipo1a8LOzg5t27bFRx99hPj4eGg0GqN2dd8eijOhZNq0afD29kbNmjX1oxrFPWZbXtjZ2WHnzp3o06cPHB0dTVavtWrVwunTpzFv3jy4ubnBxsYG1tbWcHFxgY+PDyIiIl7o3gkLFixAYGAgXF1dYW1tDWdnZ8yfPx8zZswodBsLCwvs3bsXgwcPhr29vdnP+TKtWLECo0ePhp2dHWrWrImpU6cWOtPbnNjisra2RmRkJHx9fVG9enXY2dnBz88P3333XYnaLWvOnDkDV1dXVK9evdCY4sz0f/YskM8//xwfffQR6tWrh6pVq8LX1xdr167FzZs39de7AIAbN24gLS3NZH8SHR0NV1dXVK1a1Wgd+5an2Le8mMrSt0hCGB6k2bx5M3x8fEp07IaIyobSfj+X9f5iwYIFmDNnDsLDw3mHVyIZ6e65FR4ebrC8VC7TTUT0Mp09exaenp44duwYMjIykJKSgpUrV2LBggVwcnIq9Iw0IpKX7NepICJ62RISErB161ajSX260xOLutIgEcmHRQURlXsjR45EYmIiwsLCcPXqVTg4OKBHjx747LPPZL9bMhEVjkUFEZV7ustxz507V+lUiCo1zqkgIiIiWbCoICIiIlmwqCAiIiJZsKggIiIiWbCoICIiIlmwqCAiIiJZsKggIiIiWbCoICIiIlmwqCAiIiJZsKggIiIiWbCoICIiIlmwqCAiIiJZsKggIiIiWbCoICIiIlkUeuvzzZs3v8w8iKgUREdHv5TnYX9BVLkkJyfDycnJaHmhRYWPj0+pJkREFQf7C6LKx9PT02iZJIQQCuRCREREFQznVBAREZEsWFQQERGRLFhUEBERkSzUAMKVToKIiIjKv/8HtYoM4sTbjI0AAAAASUVORK5CYII=\n", "text/plain": [ "Equals[boolean]\n", " left:\n", " Literal[uuid]\n", " 2365b1d3-5f0b-4bf3-a7ef-ec3b70f5410d\n", " right:\n", " Literal[uuid]\n", " 95c122c4-5abc-4b96-af70-f15b85ad0889" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from uuid import uuid4 \n", "uuid_value = ibis.literal(uuid4(), type='uuid')\n", "uuid_value == ibis.literal(uuid4(), type='uuid')" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "Literal[json]\n", " {\"id\": 1}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import json\n", "json_value = ibis.literal(json.dumps({\"id\": 1}), type='json')\n", "json_value" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "Literal[jsonb]\n", " b'{\"id\": 1}'" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "jsonb_value = ibis.literal(json.dumps({\"id\": 1}).encode('utf8'), type='jsonb')\n", "jsonb_value" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another important new features on `PostgreSQL` backend is the support of new `geospatial` operations, such as\n", "\n", "* GeometryType\n", "* GeometryN\n", "* IsValid\n", "* LineLocatePoint\n", "* LineMerge\n", "* LineSubstring\n", "* OrderingEquals\n", "* Union\n", "\n", "Also, now it has support for two geospatial data types: `MULTIPOINT` and `MULTILINESTRING`.\n", "\n", "Check out the _Geospatial support_ section below to see some usage examples of geospatial operations!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### PySpark\n", "\n", "This new version also includes support for a new backend: **PySpark**!\n", "\n", "Let's do the first steps with this new backend starting with a Spark session creation." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "import os\n", "\n", "import pyspark\n", "from pyspark.sql import SparkSession\n", "import pyspark.sql.types as pt\n", "from pathlib import Path\n", "\n", "# spark session and pyspark connection\n", "spark_session = SparkSession.builder.getOrCreate()\n", "con_pyspark = ibis.pyspark.connect(session=spark_session)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use `spark` or `pandas` for reading from `CSV` file. In this example, we will use `pandas`. " ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "<class 'pandas.core.frame.DataFrame'>\n", "RangeIndex: 7300 entries, 0 to 7299\n", "Data columns (total 15 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 index 7300 non-null int64 \n", " 1 Unnamed: 0 7300 non-null int64 \n", " 2 id 7300 non-null int64 \n", " 3 bool_col 7300 non-null int64 \n", " 4 tinyint_col 7300 non-null int64 \n", " 5 smallint_col 7300 non-null int64 \n", " 6 int_col 7300 non-null int64 \n", " 7 bigint_col 7300 non-null int64 \n", " 8 float_col 7300 non-null float64\n", " 9 double_col 7300 non-null float64\n", " 10 date_string_col 7300 non-null object \n", " 11 string_col 7300 non-null int64 \n", " 12 timestamp_col 7300 non-null object \n", " 13 year 7300 non-null int64 \n", " 14 month 7300 non-null int64 \n", "dtypes: float64(2), int64(11), object(2)\n", "memory usage: 855.6+ KB\n" ] } ], "source": [ "data_directory = Path(\n", " os.path.join(\n", " os.path.dirname(ibis.__path__[0]),\n", " 'ci',\n", " 'ibis-testing-data'\n", " )\n", ")\n", "\n", "pd_df_alltypes = pd.read_csv(data_directory / 'functional_alltypes.csv')\n", "pd_df_alltypes.info()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we can create a Spark DataFrame and we will create a temporary view from this data frame. Also we should enforce the desired types for each column." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['functional_alltypes']" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def pyspark_cast(df, col_types):\n", " for col, dtype in col_types.items():\n", " df = df.withColumn(col, df[col].cast(dtype))\n", " return df\n", "\n", "ps_df_alltypes = spark_session.createDataFrame(pd_df_alltypes)\n", "\n", "ps_df_alltypes = pyspark_cast(\n", " ps_df_alltypes, {\n", " 'index': 'integer',\n", " 'Unnamed: 0': 'integer',\n", " 'id': 'integer',\n", " 'bool_col': 'boolean',\n", " 'tinyint_col': 'byte',\n", " 'smallint_col': 'short',\n", " 'int_col': 'integer',\n", " 'bigint_col': 'long',\n", " 'float_col': 'float',\n", " 'double_col': 'double',\n", " 'date_string_col': 'string',\n", " 'string_col': 'string',\n", " 'timestamp_col': 'timestamp',\n", " 'year': 'integer',\n", " 'month': 'integer'\n", " }\n", ")\n", "\n", "# use ``SparkSession`` to create a table\n", "ps_df_alltypes.createOrReplaceTempView('functional_alltypes')\n", "con_pyspark.list_tables()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Check if all columns were created with the desired data type:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "PySparkTable[table]\n", " name: functional_alltypes\n", " schema:\n", " index : int32\n", " Unnamed: 0 : int32\n", " id : int32\n", " bool_col : boolean\n", " tinyint_col : int8\n", " smallint_col : int16\n", " int_col : int32\n", " bigint_col : int64\n", " float_col : float32\n", " double_col : float64\n", " date_string_col : string\n", " string_col : string\n", " timestamp_col : timestamp\n", " year : int32\n", " month : int32" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = con_pyspark.table('functional_alltypes')\n", "t" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Different than a `SQL` backend, that returns a `SQL` statement, the returned \n", "`object` from the PySpark `compile` method is a PySpark `DataFrame`:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "pyspark.sql.dataframe.DataFrame" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "expr = t.head()\n", "expr_comp = expr.compile()\n", "type(expr_comp)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DataFrame[index: int, Unnamed: 0: int, id: int, bool_col: boolean, tinyint_col: tinyint, smallint_col: smallint, int_col: int, bigint_col: bigint, float_col: float, double_col: double, date_string_col: string, string_col: string, timestamp_col: timestamp, year: int, month: int]" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "expr_comp" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To convert the compiled expression to a Pandas `DataFrame`, you can use the `toPandas` method.\n", "The result should be the same as that returned by the `execute` method." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "assert all(expr.execute() == expr_comp.toPandas())" ] }, { "cell_type": "code", "execution_count": 15, "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>index</th>\n", " <th>Unnamed: 0</th>\n", " <th>id</th>\n", " <th>bool_col</th>\n", " <th>tinyint_col</th>\n", " <th>smallint_col</th>\n", " <th>int_col</th>\n", " <th>bigint_col</th>\n", " <th>float_col</th>\n", " <th>double_col</th>\n", " <th>date_string_col</th>\n", " <th>string_col</th>\n", " <th>timestamp_col</th>\n", " <th>year</th>\n", " <th>month</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>0</td>\n", " <td>0</td>\n", " <td>6690</td>\n", " <td>True</td>\n", " <td>0</td>\n", " <td>0</td>\n", " <td>0</td>\n", " <td>0</td>\n", " <td>0.0</td>\n", " <td>0.0</td>\n", " <td>11/01/10</td>\n", " <td>0</td>\n", " <td>2010-11-01 00:00:00.000</td>\n", " <td>2010</td>\n", " <td>11</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>1</td>\n", " <td>1</td>\n", " <td>6691</td>\n", " <td>False</td>\n", " <td>1</td>\n", " <td>1</td>\n", " <td>1</td>\n", " <td>10</td>\n", " <td>1.1</td>\n", " <td>10.1</td>\n", " <td>11/01/10</td>\n", " <td>1</td>\n", " <td>2010-11-01 00:01:00.000</td>\n", " <td>2010</td>\n", " <td>11</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>2</td>\n", " <td>2</td>\n", " <td>6692</td>\n", " <td>True</td>\n", " <td>2</td>\n", " <td>2</td>\n", " <td>2</td>\n", " <td>20</td>\n", " <td>2.2</td>\n", " <td>20.2</td>\n", " <td>11/01/10</td>\n", " <td>2</td>\n", " <td>2010-11-01 00:02:00.100</td>\n", " <td>2010</td>\n", " <td>11</td>\n", " </tr>\n", " <tr>\n", " <th>3</th>\n", " <td>3</td>\n", " <td>3</td>\n", " <td>6693</td>\n", " <td>False</td>\n", " <td>3</td>\n", " <td>3</td>\n", " <td>3</td>\n", " <td>30</td>\n", " <td>3.3</td>\n", " <td>30.3</td>\n", " <td>11/01/10</td>\n", " <td>3</td>\n", " <td>2010-11-01 00:03:00.300</td>\n", " <td>2010</td>\n", " <td>11</td>\n", " </tr>\n", " <tr>\n", " <th>4</th>\n", " <td>4</td>\n", " <td>4</td>\n", " <td>6694</td>\n", " <td>True</td>\n", " <td>4</td>\n", " <td>4</td>\n", " <td>4</td>\n", " <td>40</td>\n", " <td>4.4</td>\n", " <td>40.4</td>\n", " <td>11/01/10</td>\n", " <td>4</td>\n", " <td>2010-11-01 00:04:00.600</td>\n", " <td>2010</td>\n", " <td>11</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " index Unnamed: 0 id bool_col tinyint_col smallint_col int_col \\\n", "0 0 0 6690 True 0 0 0 \n", "1 1 1 6691 False 1 1 1 \n", "2 2 2 6692 True 2 2 2 \n", "3 3 3 6693 False 3 3 3 \n", "4 4 4 6694 True 4 4 4 \n", "\n", " bigint_col float_col double_col date_string_col string_col \\\n", "0 0 0.0 0.0 11/01/10 0 \n", "1 10 1.1 10.1 11/01/10 1 \n", "2 20 2.2 20.2 11/01/10 2 \n", "3 30 3.3 30.3 11/01/10 3 \n", "4 40 4.4 40.4 11/01/10 4 \n", "\n", " timestamp_col year month \n", "0 2010-11-01 00:00:00.000 2010 11 \n", "1 2010-11-01 00:01:00.000 2010 11 \n", "2 2010-11-01 00:02:00.100 2010 11 \n", "3 2010-11-01 00:03:00.300 2010 11 \n", "4 2010-11-01 00:04:00.600 2010 11 " ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "expr.execute()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To finish this section, we can play a little bit with some aggregation operations." ] }, { "cell_type": "code", "execution_count": 16, "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>string_col</th>\n", " <th>int_col_count</th>\n", " <th>int_col_mean</th>\n", " <th>int_col_sum</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>7</td>\n", " <td>730</td>\n", " <td>7.0</td>\n", " <td>5110</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>3</td>\n", " <td>730</td>\n", " <td>3.0</td>\n", " <td>2190</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>8</td>\n", " <td>730</td>\n", " <td>8.0</td>\n", " <td>5840</td>\n", " </tr>\n", " <tr>\n", " <th>3</th>\n", " <td>0</td>\n", " <td>730</td>\n", " <td>0.0</td>\n", " <td>0</td>\n", " </tr>\n", " <tr>\n", " <th>4</th>\n", " <td>5</td>\n", " <td>730</td>\n", " <td>5.0</td>\n", " <td>3650</td>\n", " </tr>\n", " <tr>\n", " <th>5</th>\n", " <td>6</td>\n", " <td>730</td>\n", " <td>6.0</td>\n", " <td>4380</td>\n", " </tr>\n", " <tr>\n", " <th>6</th>\n", " <td>9</td>\n", " <td>730</td>\n", " <td>9.0</td>\n", " <td>6570</td>\n", " </tr>\n", " <tr>\n", " <th>7</th>\n", " <td>1</td>\n", " <td>730</td>\n", " <td>1.0</td>\n", " <td>730</td>\n", " </tr>\n", " <tr>\n", " <th>8</th>\n", " <td>4</td>\n", " <td>730</td>\n", " <td>4.0</td>\n", " <td>2920</td>\n", " </tr>\n", " <tr>\n", " <th>9</th>\n", " <td>2</td>\n", " <td>730</td>\n", " <td>2.0</td>\n", " <td>1460</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " string_col int_col_count int_col_mean int_col_sum\n", "0 7 730 7.0 5110\n", "1 3 730 3.0 2190\n", "2 8 730 8.0 5840\n", "3 0 730 0.0 0\n", "4 5 730 5.0 3650\n", "5 6 730 6.0 4380\n", "6 9 730 9.0 6570\n", "7 1 730 1.0 730\n", "8 4 730 4.0 2920\n", "9 2 730 2.0 1460" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "expr = t\n", "expr = expr.groupby('string_col').aggregate(\n", " int_col_mean=t.int_col.mean(),\n", " int_col_sum=t.int_col.sum(),\n", " int_col_count=t.int_col.count(),\n", ")\n", "expr.execute()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Check out the PySpark Ibis backend \n", "[API documentation](https://docs.ibis-project.org/api.html#pyspark-client-experimental) \n", "and the [tutorials](https://docs.ibis-project.org/tutorial.html)\n", "for more details." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Geospatial support\n", "\n", "Currently, `ibis.omniscidb` and `ibis.postgres` are the only Ibis backends that support geospatial features.\n", "\n", "In this section we will check some geospatial features using the `PostgreSQL` backend." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['array_types',\n", " 'awards_players',\n", " 'batting',\n", " 'diamonds',\n", " 'films',\n", " 'functional_alltypes',\n", " 'geo',\n", " 'geography_columns',\n", " 'geometry_columns',\n", " 'intervals',\n", " 'not_supported_intervals',\n", " 'raster_columns',\n", " 'raster_overviews',\n", " 'spatial_ref_sys',\n", " 'tzone']" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "con_psql = ibis.postgres.connect(\n", " host='localhost',\n", " port=5432,\n", " user='postgres',\n", " password='postgres',\n", " database='ibis_testing'\n", ")\n", "con_psql.list_tables()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Two important features are that it support `shape` objects (input) and `geopandas` dataframe (output)! \n", "\n", "So, let's import `shapely` to create a simple `shape` point and polygon." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"19.0 9.0 2.0 2.0\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,20.0)\"><circle cx=\"20.0\" cy=\"10.0\" r=\"0.06\" stroke=\"#555555\" stroke-width=\"0.02\" fill=\"#66cc99\" opacity=\"0.6\" /></g></svg>" ], "text/plain": [ "<shapely.geometry.point.Point at 0x7f7f1cfecd90>" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import shapely\n", "\n", "shp_point = shapely.geometry.Point((20, 10))\n", "shp_point" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"19.2 9.2 21.599999999999998 21.6\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,40.0)\"><path fill-rule=\"evenodd\" fill=\"#66cc99\" stroke=\"#555555\" stroke-width=\"0.43200000000000005\" opacity=\"0.6\" d=\"M 20.0,10.0 L 40.0,30.0 L 40.0,20.0 L 20.0,10.0 z\" /></g></svg>" ], "text/plain": [ "<shapely.geometry.polygon.Polygon at 0x7f7f1d116850>" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "shp_polygon_1 = shapely.geometry.Polygon([(20, 10), (40, 30), (40, 20), (20, 10)])\n", "shp_polygon_1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, let's create a Ibis table expression to manipulate a \"geo\" table:" ] }, { "cell_type": "code", "execution_count": 20, "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>id</th>\n", " <th>geo_point</th>\n", " <th>geo_linestring</th>\n", " <th>geo_polygon</th>\n", " <th>geo_multipolygon</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>1</td>\n", " <td>POINT (0.00000 0.00000)</td>\n", " <td>LINESTRING (0 0, 1 1)</td>\n", " <td>POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))</td>\n", " <td>(POLYGON ((30 20, 45 40, 10 40, 30 20)), POLYG...</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>2</td>\n", " <td>POINT (1.00000 1.00000)</td>\n", " <td>LINESTRING (1 1, 2 2)</td>\n", " <td>POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), ...</td>\n", " <td>(POLYGON ((40 40, 20 45, 45 30, 40 40)), POLYG...</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>3</td>\n", " <td>POINT (2.00000 2.00000)</td>\n", " <td>LINESTRING (2 2, 3 3)</td>\n", " <td>POLYGON ((2 2, 3 3, 4 4, 5 5, 5 2, 2 2))</td>\n", " <td>(POLYGON ((2 2, 3 3, 4 4, 5 5, 5 2, 2 2)))</td>\n", " </tr>\n", " <tr>\n", " <th>3</th>\n", " <td>4</td>\n", " <td>POINT (3.00000 3.00000)</td>\n", " <td>LINESTRING (3 3, 4 4)</td>\n", " <td>POLYGON ((3 3, 4 4, 5 5, 6 6, 6 3, 3 3))</td>\n", " <td>(POLYGON ((3 3, 4 4, 5 5, 6 6, 6 3, 3 3)))</td>\n", " </tr>\n", " <tr>\n", " <th>4</th>\n", " <td>5</td>\n", " <td>POINT (4.00000 4.00000)</td>\n", " <td>LINESTRING (4 4, 5 5)</td>\n", " <td>POLYGON ((4 4, 5 5, 6 6, 7 7, 7 4, 4 4))</td>\n", " <td>(POLYGON ((4 4, 5 5, 6 6, 7 7, 7 4, 4 4)))</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " id geo_point geo_linestring \\\n", "0 1 POINT (0.00000 0.00000) LINESTRING (0 0, 1 1) \n", "1 2 POINT (1.00000 1.00000) LINESTRING (1 1, 2 2) \n", "2 3 POINT (2.00000 2.00000) LINESTRING (2 2, 3 3) \n", "3 4 POINT (3.00000 3.00000) LINESTRING (3 3, 4 4) \n", "4 5 POINT (4.00000 4.00000) LINESTRING (4 4, 5 5) \n", "\n", " geo_polygon \\\n", "0 POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10)) \n", "1 POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), ... \n", "2 POLYGON ((2 2, 3 3, 4 4, 5 5, 5 2, 2 2)) \n", "3 POLYGON ((3 3, 4 4, 5 5, 6 6, 6 3, 3 3)) \n", "4 POLYGON ((4 4, 5 5, 6 6, 7 7, 7 4, 4 4)) \n", "\n", " geo_multipolygon \n", "0 (POLYGON ((30 20, 45 40, 10 40, 30 20)), POLYG... \n", "1 (POLYGON ((40 40, 20 45, 45 30, 40 40)), POLYG... \n", "2 (POLYGON ((2 2, 3 3, 4 4, 5 5, 5 2, 2 2))) \n", "3 (POLYGON ((3 3, 4 4, 5 5, 6 6, 6 3, 3 3))) \n", "4 (POLYGON ((4 4, 5 5, 6 6, 7 7, 7 4, 4 4))) " ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t_geo = con_psql.table('geo')\n", "df_geo = t_geo.execute()\n", "df_geo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And the type of `df_geo` is ... a `geopandas` dataframe!" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "geopandas.geodataframe.GeoDataFrame" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(df_geo)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So you can take the advantage of GeoPandas features too!" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "df_geo.set_geometry('geo_multipolygon').head(1).plot();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, let's check if there are any `geo_multipolygon`'s that contain the `shape` point we just created. " ] }, { "cell_type": "code", "execution_count": 23, "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>geo_multipolygon</th>\n", " <th>contains_point_1</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>MULTIPOLYGON (((30.00000 20.00000, 45.00000 40...</td>\n", " <td>True</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>MULTIPOLYGON (((40.00000 40.00000, 20.00000 45...</td>\n", " <td>True</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>MULTIPOLYGON (((2.00000 2.00000, 3.00000 3.000...</td>\n", " <td>False</td>\n", " </tr>\n", " <tr>\n", " <th>3</th>\n", " <td>MULTIPOLYGON (((3.00000 3.00000, 4.00000 4.000...</td>\n", " <td>False</td>\n", " </tr>\n", " <tr>\n", " <th>4</th>\n", " <td>MULTIPOLYGON (((4.00000 4.00000, 5.00000 5.000...</td>\n", " <td>False</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " geo_multipolygon contains_point_1\n", "0 MULTIPOLYGON (((30.00000 20.00000, 45.00000 40... True\n", "1 MULTIPOLYGON (((40.00000 40.00000, 20.00000 45... True\n", "2 MULTIPOLYGON (((2.00000 2.00000, 3.00000 3.000... False\n", "3 MULTIPOLYGON (((3.00000 3.00000, 4.00000 4.000... False\n", "4 MULTIPOLYGON (((4.00000 4.00000, 5.00000 5.000... False" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t_geo[\n", " t_geo.geo_multipolygon, \n", " t_geo['geo_multipolygon'].contains(shp_point).name('contains_point_1')\n", "].execute()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So, as expected, just the first two `multipolygon`s contain a `point` with coordinates `(20, 10)`.\n", "\n", "For more examples of Geospatial Analysis with Ibis, \n", "check this nice [tutorial](https://docs.ibis-project.org/notebooks/tutorial/11-Geospatial-Analysis.html)\n", "written by [Ian Rose](https://github.com/ian-r-rose)!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Python versions support\n", "\n", "Ibis 1.3 added initial support for Python 3.8 and dropped support for Python 3.5. \n", "\n", "> Note: currently, the [OmniSciDB](https://github.com/ibis-project/ibis/issues/2090) and \n", "[PySpark](https://github.com/ibis-project/ibis/issues/2091) backends\n", "are not supported on Python 3.8." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Final words\n", "\n", "**Do you want to play more with Ibis framework?**\n", "\n", "You can install it from PyPI:\n", "\n", "```\n", "python -m pip install --upgrade ibis-framework==1.3.0\n", "```\n", "\n", "Or from conda-forge:\n", "\n", "```\n", "conda install ibis-framework=1.3.0 -c conda-forge\n", "```\n", "\n", "Check out some interesting tutorials to help you to start on Ibis: https://docs.ibis-project.org/tutorial.html. If you are coming from the SQL world, maybe [Ibis for SQL Programmers](https://docs.ibis-project.org/sql.html) documentation section will be helpful. Have fun!\n" ] } ], "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.7.3" }, "nikola": { "author": "Ivan Ogasawara", "date": "2020-05-02 03:30:00 UTC", "slug": "ibis-1.3-release", "tags": "Ibis", "title": "Highlights of the Ibis 1.3 release" } }, "nbformat": 4, "nbformat_minor": 4 }