PageSourceSearch

https://ibis-project.org/

html ibis-project.org collected 2026-09-24 10:09:03 UTC 125,041 bytes, 1,762 lines download raw bytes

1<!DOCTYPE html>
2<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
3
4<meta charset="utf-8">
5<meta name="generator" content="quarto-1.9.18">
6
7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
9<meta name="description" content="the portable Python dataframe library">
10
11<title>Ibis</title>
12<style>
13/* Default styles provided by pandoc.
14** See https://pandoc.org/MANUAL.html#variables-for-html for config info.
15*/
16code{white-space: pre-wrap;}
17span.smallcaps{font-variant: small-caps;}
18div.columns{display: flex; gap: min(4vw, 1.5em);}
19div.column{flex: auto; overflow-x: auto;}
20div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
21ul.task-list{list-style: none;}
22ul.task-list li input[type="checkbox"] {
23  width: 0.8em;
24  margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 
25  vertical-align: middle;
26}
27/* CSS for syntax highlighting */
28html { -webkit-text-size-adjust: 100%; }
29pre > code.sourceCode { white-space: pre; position: relative; }
30pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
31pre > code.sourceCode > span:empty { height: 1.2em; }
32.sourceCode { overflow: visible; }
33code.sourceCode > span { color: inherit; text-decoration: inherit; }
34div.sourceCode { margin: 1em 0; }
35pre.sourceCode { margin: 0; }
36@media screen {
37div.sourceCode { overflow: auto; }
38}
39@media print {
40pre > code.sourceCode { white-space: pre-wrap; }
41pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
42}
43pre.numberSource code
44  { counter-reset: source-line 0; }
45pre.numberSource code > span
46  { position: relative; left: -4em; counter-increment: source-line; }
47pre.numberSource code > span > a:first-child::before
48  { content: counter(source-line);
49    position: relative; left: -1em; text-align: right; vertical-align: baseline;
50    border: none; display: inline-block;
51    -webkit-touch-callout: none; -webkit-user-select: none;
52    -khtml-user-select: none; -moz-user-select: none;
53    -ms-user-select: none; user-select: none;
54    padding: 0 4px; width: 4em;
55  }
56pre.numberSource { margin-left: 3em;  padding-left: 4px; }
57div.sourceCode
58  {   }
59@media screen {
60pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
61}
62</style>
63
64
65<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js" integrity="sha384-ZvpUoO/+PpLXR1lu4jmpXWu80pZlYUAfxl5NsBMWOEPSjUn/6Z/hRTt8+pR6L4N2" crossorigin="anonymous"></script>
65<script src="site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 65
65
66<script src="site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 66
66
67<script src="site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 67
67
68<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
vendor: 1 bytes, line 68
68
69<script src="site_libs/quarto-search/fuse.min.js"></script>
vendor: 1 bytes, line 69
69
70<script src="site_libs/quarto-search/quarto-search.js"></script>
vendor: 1 bytes, line 70
70
71<script src="site_libs/quarto-search/autocomplete-preset-algolia.umd.js"></script>
71
72<meta name="quarto:offset" content="./">
73<link href="./logo.svg" rel="icon" type="image/svg+xml">
74<script src="site_libs/quarto-html/quarto.js" type="module"></script>
vendor: 1 bytes, line 74
74
75<script src="site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
vendor: 1 bytes, line 75
75
76<script src="site_libs/quarto-html/axe/axe-check.js" type="module"></script>
vendor: 1 bytes, line 76
76
77<script src="site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 77
77
78<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
78
79<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
80<link href="site_libs/quarto-html/quarto-syntax-highlighting-fafd091245ca516cc2c8c2b2c7d0cd5e.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
81<link href="site_libs/quarto-html/quarto-syntax-highlighting-dark-8d865482300dacf2543a97eef29e18b5.css" rel="stylesheet" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
82<link href="site_libs/quarto-html/quarto-syntax-highlighting-fafd091245ca516cc2c8c2b2c7d0cd5e.css" rel="stylesheet" class="quarto-color-scheme-extra" id="quarto-text-highlighting-styles">
83<script src="site_libs/bootstrap/bootstrap.min.js"></script>
83
84<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
85<link href="site_libs/bootstrap/bootstrap-e4b02b9d8ec73f0e62ff208b9459ea2c.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
86<link href="site_libs/bootstrap/bootstrap-dark-a025b3cfc189dfe3454a41e1472c33fe.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
87<link href="site_libs/bootstrap/bootstrap-e4b02b9d8ec73f0e62ff208b9459ea2c.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme-extra" id="quarto-bootstrap" data-mode="light">
88<script id="quarto-search-options" type="application/json">{
89  "location": "navbar",
90  "copy-button": false,
91  "collapse-after": 3,
92  "panel-placement": "end",
93  "type": "overlay",
94  "limit": 50,
95  "algolia": {
96    "application-id": "TNU9HG3L41",
97    "search-only-api-key": "26350948d1961209df16d9717a7e01d6",
98    "index-name": "prod_ibis",
99    "analytics-events": true,
100    "show-logo": true,
101    "libDir": "site_libs",
102    "cookie-consent-enabled": false
103  },
104  "keyboard-shortcut": [
105    "f",
106    "/",
107    "s"
108  ],
109  "language": {
110    "search-no-results-text": "No results",
111    "search-matching-documents-text": "matching documents",
112    "search-copy-link-title": "Copy link to search",
113    "search-hide-matches-text": "Hide additional matches",
114    "search-more-match-text": "more match in this document",
115    "search-more-matches-text": "more matches in this document",
116    "search-clear-button-title": "Clear",
117    "search-text-placeholder": "",
118    "search-detached-cancel-button-title": "Cancel",
119    "search-submit-button-title": "Submit",
120    "search-label": "Search"
121  }
122}</script>
vendor: 1 bytes, line 122
122
123<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/algoliasearch-lite.umd.js"></script>
123
124
125
126<script type="text/javascript">
127var ALGOLIA_INSIGHTS_SRC = "https://cdn.jsdelivr.net/npm/search-insights/dist/search-insights.iife.min.js";
128!function(e,a,t,n,s,i,c){e.AlgoliaAnalyticsObject=s,e[s]=e[s]||function(){
129(e[s].queue=e[s].queue||[]).push(arguments)},i=a.createElement(t),c=a.getElementsByTagName(t)[0],
130i.async=1,i.src=n,c.parentNode.insertBefore(i,c)
131}(window,document,"script",ALGOLIA_INSIGHTS_SRC,"aa");
132</script>
132
133
134<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-plugin-algolia-insights">
135
136</script>
vendor: 1 bytes, line 136
136
137<script src="https://cdn.jsdelivr.net/npm/[email protected]/require.min.js" integrity="sha384-c9c+LnTbwQ3aujuU7ULEPVvgLs+Fn6fJUvIGTsuu1ZcCf11fiEubah0ttpca4ntM sha384-6V1/AdqZRWk1KAlWbKBlGhN7VG4iE/yAZcO6NZPMF8od0vukrvr0tg4qY6NSrItx" crossorigin="anonymous"></script>
137
138
139<script type="application/javascript">define('jquery', [],function() {return window.jQuery;})</script>
vendor: 1 bytes, line 139
139
140<script type="text/javascript">
141window.PlotlyConfig = {MathJaxConfig: 'local'};
142if (window.MathJax && window.MathJax.Hub && window.MathJax.Hub.Config) {window.MathJax.Hub.Config({SVG: {font: "STIX-Web"}});}
143</script>
vendor: 1 bytes, line 143
143
144<script type="module">import "https://cdn.plot.ly/plotly-3.3.1.min"</script>
144
145
146<script data-goatcounter="https://ibis.goatcounter.com/count" async="" src="//gc.zgo.at/count.js"></script>
vendor: 1 bytes, line 146
146
147<script data-goatcounter="https://ibis.goatcounter.com/count" async="" src="//gc.zgo.at/count.js"></script>
147
148
149
150<link rel="stylesheet" href="styles.css">
151<meta property="og:title" content="Ibis">
152<meta property="og:description" content="the portable Python dataframe library">
153<meta property="og:image" content="https://ibis-project.org/logo.png">
154<meta property="og:site_name" content="Ibis">
155<meta property="og:image:height" content="756">
156<meta property="og:image:width" content="756">
157<meta name="twitter:title" content="Ibis">
158<meta name="twitter:description" content="the portable Python dataframe library">
159<meta name="twitter:image" content="https://ibis-project.org/logo.png">
160<meta name="twitter:image-height" content="756">
161<meta name="twitter:image-width" content="756">
162<meta name="twitter:card" content="summary_large_image">
163</head>
164
165<body class="nav-fixed fullcontent quarto-light">
165<script id="quarto-html-before-body" type="application/javascript">
166    const toggleBodyColorMode = (bsSheetEl) => {
167      const mode = bsSheetEl.getAttribute("data-mode");
168      const bodyEl = window.document.querySelector("body");
169      if (mode === "dark") {
170        bodyEl.classList.add("quarto-dark");
171        bodyEl.classList.remove("quarto-light");
172      } else {
173        bodyEl.classList.add("quarto-light");
174        bodyEl.classList.remove("quarto-dark");
175      }
176    }
177    const toggleBodyColorPrimary = () => {
178      const bsSheetEl = window.document.querySelector("link#quarto-bootstrap:not([rel=disabled-stylesheet])");
179      if (bsSheetEl) {
180        toggleBodyColorMode(bsSheetEl);
181      }
182    }
183    const setColorSchemeToggle = (alternate) => {
184      const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle');
185      for (let i=0; i < toggles.length; i++) {
186        const toggle = toggles[i];
187        if (toggle) {
188          if (alternate) {
189            toggle.classList.add("alternate");
190          } else {
191            toggle.classList.remove("alternate");
192          }
193        }
194      }
195    };
196    const toggleColorMode = (alternate) => {
197      // Switch the stylesheets
198      const primaryStylesheets = window.document.querySelectorAll('link.quarto-color-scheme:not(.quarto-color-alternate)');
199      const alternateStylesheets = window.document.querySelectorAll('link.quarto-color-scheme.quarto-color-alternate');
200      manageTransitions('#quarto-margin-sidebar .nav-link', false);
201      if (alternate) {
202        // note: dark is layered on light, we don't disable primary!
203        enableStylesheet(alternateStylesheets);
204        for (const sheetNode of alternateStylesheets) {
205          if (sheetNode.id === "quarto-bootstrap") {
206            toggleBodyColorMode(sheetNode);
207          }
208        }
209      } else {
210        disableStylesheet(alternateStylesheets);
211        enableStylesheet(primaryStylesheets)
212        toggleBodyColorPrimary();
213      }
214      manageTransitions('#quarto-margin-sidebar .nav-link', true);
215      // Switch the toggles
216      setColorSchemeToggle(alternate)
217      // Hack to workaround the fact that safari doesn't
218      // properly recolor the scrollbar when toggling (#1455)
219      if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) {
220        manageTransitions("body", false);
221        window.scrollTo(0, 1);
222        setTimeout(() => {
223          window.scrollTo(0, 0);
224          manageTransitions("body", true);
225        }, 40);
226      }
227    }
228    const disableStylesheet = (stylesheets) => {
229      for (let i=0; i < stylesheets.length; i++) {
230        const stylesheet = stylesheets[i];
231        stylesheet.rel = 'disabled-stylesheet';
232      }
233    }
234    const enableStylesheet = (stylesheets) => {
235      for (let i=0; i < stylesheets.length; i++) {
236        const stylesheet = stylesheets[i];
237        if(stylesheet.rel !== 'stylesheet') { // for Chrome, which will still FOUC without this check
238          stylesheet.rel = 'stylesheet';
239        }
240      }
241    }
242    const manageTransitions = (selector, allowTransitions) => {
243      const els = window.document.querySelectorAll(selector);
244      for (let i=0; i < els.length; i++) {
245        const el = els[i];
246        if (allowTransitions) {
247          el.classList.remove('notransition');
248        } else {
249          el.classList.add('notransition');
250        }
251      }
252    }
253    const isFileUrl = () => {
254      return window.location.protocol === 'file:';
255    }
256    const hasAlternateSentinel = () => {
257      let styleSentinel = getColorSchemeSentinel();
258      if (styleSentinel !== null) {
259        return styleSentinel === "alternate";
260      } else {
261        return false;
262      }
263    }
264    const setStyleSentinel = (alternate) => {
265      const value = alternate ? "alternate" : "default";
266      if (!isFileUrl()) {
267        window.localStorage.setItem("quarto-color-scheme", value);
268      } else {
269        localAlternateSentinel = value;
270      }
271    }
272    const getColorSchemeSentinel = () => {
273      if (!isFileUrl()) {
274        const storageValue = window.localStorage.getItem("quarto-color-scheme");
275        return storageValue != null ? storageValue : localAlternateSentinel;
276      } else {
277        return localAlternateSentinel;
278      }
279    }
280    const toggleGiscusIfUsed = (isAlternate, darkModeDefault) => {
281      const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light';
282      const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark';
283      let newTheme = '';
284      if(authorPrefersDark) {
285        newTheme = isAlternate ? baseTheme : alternateTheme;
286      } else {
287        newTheme = isAlternate ? alternateTheme : baseTheme;
288      }
289      const changeGiscusTheme = () => {
290        // From: https://github.com/giscus/giscus/issues/336
291        const sendMessage = (message) => {
292          const iframe = document.querySelector('iframe.giscus-frame');
293          if (!iframe) return;
294          iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
295        }
296        sendMessage({
297          setConfig: {
298            theme: newTheme
299          }
300        });
301      }
302      const isGiscussLoaded = window.document.querySelector('iframe.giscus-frame') !== null;
303      if (isGiscussLoaded) {
304        changeGiscusTheme();
305      }
306    };
307    const authorPrefersDark = false;
308    const darkModeDefault = authorPrefersDark;
309      document.querySelector('link#quarto-text-highlighting-styles.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
310      document.querySelector('link#quarto-bootstrap.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
311    let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default';
312    // Dark / light mode switch
313    window.quartoToggleColorScheme = () => {
314      // Read the current dark / light value
315      let toAlternate = !hasAlternateSentinel();
316      toggleColorMode(toAlternate);
317      setStyleSentinel(toAlternate);
318      toggleGiscusIfUsed(toAlternate, darkModeDefault);
319      window.dispatchEvent(new Event('resize'));
320    };
321    // Switch to dark mode if need be
322    if (hasAlternateSentinel()) {
323      toggleColorMode(true);
324    } else {
325      toggleColorMode(false);
326    }
327  </script>
327
328
329<div id="quarto-search-results"></div>
330  <header id="quarto-header" class="headroom fixed-top">
331    <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
332      <div class="navbar-container container-fluid">
333      <div class="navbar-brand-container mx-auto">
334    <a class='navbar-brand navbar-brand-logo' href='/'>
335    <img src="./logo.svg" alt="" class="navbar-logo light-content">
336    <img src="./logo.svg" alt="" class="navbar-logo dark-content">
337    </a>
338    <a class='navbar-brand' href='/'>
339    <span class="navbar-title">Ibis</span>
340    </a>
341  </div>
342            <div id="quarto-search" class="" title="Search"></div>
343          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" role="menu" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
344  <span class="navbar-toggler-icon"></span>
345</button>
346          <div class="collapse navbar-collapse" id="navbarCollapse">
347            <ul class="navbar-nav navbar-nav-scroll me-auto">
348  <li class="nav-item dropdown ">
349    <a class="nav-link dropdown-toggle" href="#" id="nav-menu-getting-started" role="link" data-bs-toggle="dropdown" aria-expanded="false">
350 <span class="menu-text">Getting started</span>
351    </a>
352    <ul class="dropdown-menu" aria-labelledby="nav-menu-getting-started">    
353        <li>
354    <a class='dropdown-item' href='/tutorials/basics'>
355 <span class="dropdown-text">10 minutes to Ibis</span></a>
356  </li>  
357        <li>
358    <a class='dropdown-item' href='/install'>
359 <span class="dropdown-text">Installation</span></a>
360  </li>  
361        <li>
362    <a class='dropdown-item' href='/tutorials/browser/repl'>
363 <span class="dropdown-text">Online playground</span></a>
364  </li>  
365        <li><hr class="dropdown-divider"></li>
366        <li class="dropdown-header">Coming from …</li>
367        <li>
368    <a class='dropdown-item' href='/tutorials/coming-from/dplyr'>
369 <span class="dropdown-text">dplyr</span></a>
370  </li>  
371        <li>
372    <a class='dropdown-item' href='/tutorials/coming-from/pandas'>
373 <span class="dropdown-text">pandas</span></a>
374  </li>  
375        <li>
376    <a class='dropdown-item' href='/tutorials/coming-from/sql'>
377 <span class="dropdown-text">SQL</span></a>
378  </li>  
379        <li><hr class="dropdown-divider"></li>
380        <li class="dropdown-header">Backend examples</li>
381        <li>
382    <a class='dropdown-item' href='/tutorials/backends/clickhouse'>
383 <span class="dropdown-text">ClickHouse</span></a>
384  </li>  
385        <li>
386    <a class='dropdown-item' href='/tutorials/backends/apache-flink/0_setup'>
387 <span class="dropdown-text">Apache Flink</span></a>
388  </li>  
389        <li>
390    <a class='dropdown-item' href='/tutorials/backends/starburst-galaxy/0_setup'>
391 <span class="dropdown-text">Starburst Galaxy</span></a>
392  </li>  
393    </ul>
394  </li>
395  <li class="nav-item dropdown ">
396    <a class="nav-link dropdown-toggle" href="#" id="nav-menu-concepts" role="link" data-bs-toggle="dropdown" aria-expanded="false">
397 <span class="menu-text">Concepts</span>
398    </a>
399    <ul class="dropdown-menu" aria-labelledby="nav-menu-concepts">    
400        <li>
401    <a class='dropdown-item' href='/why'>
402 <span class="dropdown-text">Why Ibis?</span></a>
403  </li>  
404        <li>
405    <a class='dropdown-item' href='/concepts/backend-table-hierarchy'>
406 <span class="dropdown-text">Backend Table Hierarchy</span></a>
407  </li>  
408        <li>
409    <a class='dropdown-item' href='/concepts/casting'>
410 <span class="dropdown-text">Casting between datatypes</span></a>
411  </li>  
412        <li>
413    <a class='dropdown-item' href='/concepts/composable-ecosystem'>
414 <span class="dropdown-text">Composable data ecosystem</span></a>
415  </li>  
416        <li>
417    <a class='dropdown-item' href='/concepts/datatypes'>
418 <span class="dropdown-text">Datatypes and Datashapes</span></a>
419  </li>  
420        <li>
421    <a class='dropdown-item' href='/concepts/internals'>
422 <span class="dropdown-text">Internals</span></a>
423  </li>  
424        <li>
425    <a class='dropdown-item' href='/concepts/user-testimonials'>
426 <span class="dropdown-text">User testimonials</span></a>
427  </li>  
428        <li>
429    <a class='dropdown-item' href='/concepts/versioning'>
430 <span class="dropdown-text">Versioning policy</span></a>
431  </li>  
432        <li>
433    <a class='dropdown-item' href='/concepts/who'>
434 <span class="dropdown-text">Who supports Ibis?</span></a>
435  </li>  
436    </ul>
437  </li>
438  <li class="nav-item dropdown ">
439    <a class="nav-link dropdown-toggle" href="#" id="nav-menu-backends" role="link" data-bs-toggle="dropdown" aria-expanded="false">
440 <span class="menu-text">Backends</span>
441    </a>
442    <ul class="dropdown-menu" aria-labelledby="nav-menu-backends">    
443        <li>
444    <a class='dropdown-item' href='/backends/athena'>
445 <span class="dropdown-text">Amazon Athena</span></a>
446  </li>  
447        <li>
448    <a class='dropdown-item' href='/backends/bigquery'>
449 <span class="dropdown-text">BigQuery</span></a>
450  </li>  
451        <li>
452    <a class='dropdown-item' href='/backends/clickhouse'>
453 <span class="dropdown-text">ClickHouse</span></a>
454  </li>  
455        <li>
456    <a class='dropdown-item' href='/backends/dask'>
457 <span class="dropdown-text">Dask</span></a>
458  </li>  
459        <li>
460    <a class='dropdown-item' href='/backends/databricks'>
461 <span class="dropdown-text">Databricks</span></a>
462  </li>  
463        <li>
464    <a class='dropdown-item' href='/backends/datafusion'>
465 <span class="dropdown-text">DataFusion</span></a>
466  </li>  
467        <li>
468    <a class='dropdown-item' href='/backends/druid'>
469 <span class="dropdown-text">Druid</span></a>
470  </li>  
471        <li>
472    <a class='dropdown-item' href='/backends/duckdb'>
473 <span class="dropdown-text">DuckDB</span></a>
474  </li>  
475        <li>
476    <a class='dropdown-item' href='/backends/exasol'>
477 <span class="dropdown-text">Exasol</span></a>
478  </li>  
479        <li>
480    <a class='dropdown-item' href='/backends/flink'>
481 <span class="dropdown-text">Flink</span></a>
482  </li>  
483        <li>
484    <a class='dropdown-item' href='/backends/impala'>
485 <span class="dropdown-text">Impala</span></a>
486  </li>  
487        <li>
488    <a class='dropdown-item' href='/backends/materialize'>
489 <span class="dropdown-text">Materialize</span></a>
490  </li>  
491        <li>
492    <a class='dropdown-item' href='/backends/mssql'>
493 <span class="dropdown-text">MSSQL</span></a>
494  </li>  
495        <li>
496    <a class='dropdown-item' href='/backends/mysql'>
497 <span class="dropdown-text">MySQL</span></a>
498  </li>  
499        <li>
500    <a class='dropdown-item' href='/backends/oracle'>
501 <span class="dropdown-text">Oracle</span></a>
502  </li>  
503        <li>
504    <a class='dropdown-item' href='/backends/pandas'>
505 <span class="dropdown-text">pandas</span></a>
506  </li>  
507        <li>
508    <a class='dropdown-item' href='/backends/polars'>
509 <span class="dropdown-text">Polars</span></a>
510  </li>  
511        <li>
512    <a class='dropdown-item' href='/backends/postgresql'>
513 <span class="dropdown-text">PostgreSQL</span></a>
514  </li>  
515        <li>
516    <a class='dropdown-item' href='/backends/pyspark'>
517 <span class="dropdown-text">PySpark</span></a>
518  </li>  
519        <li>
520    <a class='dropdown-item' href='/backends/risingwave'>
521 <span class="dropdown-text">RisingWave</span></a>
522  </li>  
523        <li>
524    <a class='dropdown-item' href='/backends/singlestoredb'>
525 <span class="dropdown-text">SingleStoreDB</span></a>
526  </li>  
527        <li>
528    <a class='dropdown-item' href='/backends/snowflake'>
529 <span class="dropdown-text">Snowflake</span></a>
530  </li>  
531        <li>
532    <a class='dropdown-item' href='/backends/sqlite'>
533 <span class="dropdown-text">SQLite</span></a>
534  </li>  
535        <li>
536    <a class='dropdown-item' href='/backends/trino'>
537 <span class="dropdown-text">Trino</span></a>
538  </li>  
539        <li><hr class="dropdown-divider"></li>
540        <li class="dropdown-header">Support</li>
541        <li>
542    <a class='dropdown-item' href='/backends/support/cloud_support_policy'>
543 <span class="dropdown-text">Cloud backend support policy</span></a>
544  </li>  
545        <li>
546    <a class='dropdown-item' href='/backends/support/matrix'>
547 <span class="dropdown-text">Operation support matrix</span></a>
548  </li>  
549        <li>
550    <a class='dropdown-item' href='/reference/operations'>
551 <span class="dropdown-text">Operations</span></a>
552  </li>  
553    </ul>
554  </li>
555  <li class="nav-item dropdown ">
556    <a class="nav-link dropdown-toggle" href="#" id="nav-menu-how-to" role="link" data-bs-toggle="dropdown" aria-expanded="false">
557 <span class="menu-text">How-to</span>
558    </a>
559    <ul class="dropdown-menu" aria-labelledby="nav-menu-how-to">    
560        <li class="dropdown-header">Configure</li>
561        <li>
562    <a class='dropdown-item' href='/how-to/configure/basics'>
563 <span class="dropdown-text">Basic configuration</span></a>
564  </li>  
565        <li><hr class="dropdown-divider"></li>
566        <li class="dropdown-header">Input Output</li>
567        <li>
568    <a class='dropdown-item' href='/how-to/input-output/basics'>
569 <span class="dropdown-text">Basic input/output</span></a>
570  </li>  
571        <li>
572    <a class='dropdown-item' href='/how-to/input-output/duckdb-parquet'>
573 <span class="dropdown-text">Read parquet files with Ibis</span></a>
574  </li>  
575        <li>
576    <a class='dropdown-item' href='/how-to/input-output/gcs_duckdb'>
577 <span class="dropdown-text">Loading Google Cloud Storage files with DuckDB</span></a>
578  </li>  
579        <li>
580    <a class='dropdown-item' href='/how-to/input-output/multiple-backends'>
581 <span class="dropdown-text">Work with multiple backends</span></a>
582  </li>  
583        <li><hr class="dropdown-divider"></li>
584        <li class="dropdown-header">Analytics</li>
585        <li>
586    <a class='dropdown-item' href='/how-to/analytics/basics'>
587 <span class="dropdown-text">Basic analytics</span></a>
588  </li>  
589        <li>
590    <a class='dropdown-item' href='/how-to/analytics/chain_expressions'>
591 <span class="dropdown-text">Chaining expressions</span></a>
592  </li>  
593        <li>
594    <a class='dropdown-item' href='/how-to/analytics/imdb'>
595 <span class="dropdown-text">Analyze IMDB data using Ibis</span></a>
596  </li>  
597        <li><hr class="dropdown-divider"></li>
598        <li class="dropdown-header">Visualization</li>
599        <li>
600    <a class='dropdown-item' href='/how-to/visualization/altair'>
601 <span class="dropdown-text">Altair + Ibis</span></a>
602  </li>  
603        <li>
604    <a class='dropdown-item' href='/how-to/visualization/graphs'>
605 <span class="dropdown-text">GraphViz + Ibis</span></a>
606  </li>  
607        <li>
608    <a class='dropdown-item' href='/how-to/visualization/marimo'>
609 <span class="dropdown-text">marimo + Ibis</span></a>
610  </li>  
611        <li>
612    <a class='dropdown-item' href='/how-to/visualization/matplotlib'>
613 <span class="dropdown-text">matplotlib + Ibis</span></a>
614  </li>  
615        <li>
616    <a class='dropdown-item' href='/how-to/visualization/plotly'>
617 <span class="dropdown-text">Plotly + Ibis</span></a>
618  </li>  
619        <li>
620    <a class='dropdown-item' href='/how-to/visualization/plotnine'>
621 <span class="dropdown-text">plotnine + Ibis</span></a>
622  </li>  
623        <li>
624    <a class='dropdown-item' href='/how-to/visualization/seaborn'>
625 <span class="dropdown-text">seaborn + Ibis</span></a>
626  </li>  
627        <li>
628    <a class='dropdown-item' href='/how-to/visualization/streamlit'>
629 <span class="dropdown-text">Streamlit + Ibis</span></a>
630  </li>  
631        <li><hr class="dropdown-divider"></li>
632        <li class="dropdown-header">Extending</li>
633        <li>
634    <a class='dropdown-item' href='/how-to/extending/builtin'>
635 <span class="dropdown-text">Reference built-in functions</span></a>
636  </li>  
637        <li>
638    <a class='dropdown-item' href='/how-to/extending/sql'>
639 <span class="dropdown-text">Using SQL strings with Ibis</span></a>
640  </li>  
641        <li>
642    <a class='dropdown-item' href='/how-to/extending/streaming'>
643 <span class="dropdown-text">Ibis for streaming</span></a>
644  </li>  
645        <li>
646    <a class='dropdown-item' href='/how-to/extending/unbound_expression'>
647 <span class="dropdown-text">Write and execute unbound expressions</span></a>
648  </li>  
649    </ul>
650  </li>
651  <li class="nav-item dropdown ">
652    <a class="nav-link dropdown-toggle" href="#" id="nav-menu-reference" role="link" data-bs-toggle="dropdown" aria-expanded="false">
653 <span class="menu-text">Reference</span>
654    </a>
655    <ul class="dropdown-menu" aria-labelledby="nav-menu-reference">    
656        <li class="dropdown-header">Expression API</li>
657        <li>
658    <a class='dropdown-item' href='/reference/expression-tables'>
659 <span class="dropdown-text">Table expressions</span></a>
660  </li>  
661        <li>
662    <a class='dropdown-item' href='/reference/selectors'>
663 <span class="dropdown-text">Column selectors</span></a>
664  </li>  
665        <li>
666    <a class='dropdown-item' href='/reference/expression-generic'>
667 <span class="dropdown-text">Generic expressions</span></a>
668  </li>  
669        <li>
670    <a class='dropdown-item' href='/reference/expression-numeric'>
671 <span class="dropdown-text">Numeric and Boolean expressions</span></a>
672  </li>  
673        <li>
674    <a class='dropdown-item' href='/reference/expression-strings'>
675 <span class="dropdown-text">String expressions</span></a>
676  </li>  
677        <li>
678    <a class='dropdown-item' href='/reference/expression-temporal'>
679 <span class="dropdown-text">Temporal expressions</span></a>
680  </li>  
681        <li>
682    <a class='dropdown-item' href='/reference/expression-collections'>
683 <span class="dropdown-text">Collection expressions</span></a>
684  </li>  
685        <li>
686    <a class='dropdown-item' href='/reference/expression-json'>
687 <span class="dropdown-text">JSON expressions</span></a>
688  </li>  
689        <li>
690    <a class='dropdown-item' href='/reference/expression-geospatial'>
691 <span class="dropdown-text">Geospatial expressions</span></a>
692  </li>  
693        <li>
694    <a class='dropdown-item' href='/reference/expression-misc'>
695 <span class="dropdown-text">UUIDs, INET, MACADDR expressions</span></a>
696  </li>  
697        <li><hr class="dropdown-divider"></li>
698        <li class="dropdown-header">Type system</li>
699        <li>
700    <a class='dropdown-item' href='/reference/datatypes'>
701 <span class="dropdown-text">Data types</span></a>
702  </li>  
703        <li>
704    <a class='dropdown-item' href='/reference/schemas'>
705 <span class="dropdown-text">Schemas</span></a>
706  </li>  
707        <li><hr class="dropdown-divider"></li>
708        <li class="dropdown-header">UDFs</li>
709        <li>
710    <a class='dropdown-item' href='/reference/scalar-udfs'>
711 <span class="dropdown-text">Scalar UDFs</span></a>
712  </li>  
713        <li>
714    <a class='dropdown-item' href='/reference/aggregate-udfs'>
715 <span class="dropdown-text">Aggregate UDFs (experimental)</span></a>
716  </li>  
717        <li><hr class="dropdown-divider"></li>
718        <li class="dropdown-header">Connection APIs</li>
719        <li>
720    <a class='dropdown-item' href='/reference/connection'>
721 <span class="dropdown-text">Top-level connection APIs</span></a>
722  </li>  
723        <li><hr class="dropdown-divider"></li>
724        <li class="dropdown-header">Configuration</li>
725        <li>
726    <a class='dropdown-item' href='/reference/interactive'>
727 <span class="dropdown-text">Interactive</span></a>
728  </li>  
729        <li>
730    <a class='dropdown-item' href='/reference/options'>
731 <span class="dropdown-text">Options</span></a>
732  </li>  
733        <li>
734    <a class='dropdown-item' href='/reference/repr'>
735 <span class="dropdown-text">
735Repr</span></a>
736  </li>  
737        <li>
738    <a class='dropdown-item' href='/reference/sql'>
739 <span class="dropdown-text">SQL</span></a>
740  </li>  
741        <li><hr class="dropdown-divider"></li>
742        <li class="dropdown-header">Cursed Knowledge</li>
743        <li>
744    <a class='dropdown-item' href='/reference/cursed_knowledge'>
745 <span class="dropdown-text">Cursed Knowledge</span></a>
746  </li>  
747    </ul>
748  </li>
749</ul>
750            <ul class="navbar-nav navbar-nav-scroll ms-auto">
751  <li class="nav-item">
752    <a class='nav-link' href='/posts'> 
753<span class="menu-text">Posts</span></a>
754  </li>  
755  <li class="nav-item">
756    <a class='nav-link' href='/presentations'> 
757<span class="menu-text">Presentations</span></a>
758  </li>  
759  <li class="nav-item">
760    <a class='nav-link' href='/release_notes'> 
761<span class="menu-text">Release notes</span></a>
762  </li>  
763  <li class="nav-item dropdown ">
764    <a class="nav-link dropdown-toggle" href="#" id="nav-menu-contribute" role="link" data-bs-toggle="dropdown" aria-expanded="false">
765 <span class="menu-text">Contribute</span>
766    </a>
767    <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="nav-menu-contribute">    
768        <li class="dropdown-header">Contribute</li>
769        <li>
770    <a class='dropdown-item' href='/contribute/01_environment'>
771 <span class="dropdown-text">Setting up a development environment</span></a>
772  </li>  
773        <li>
774    <a class='dropdown-item' href='/contribute/02_workflow'>
775 <span class="dropdown-text">Contribute to the Ibis codebase</span></a>
776  </li>  
777        <li>
778    <a class='dropdown-item' href='/contribute/03_style'>
779 <span class="dropdown-text">Style and formatting</span></a>
780  </li>  
781        <li>
782    <a class='dropdown-item' href='/contribute/04_maintainers_guide'>
783 <span class="dropdown-text">Maintaining the codebase</span></a>
784  </li>  
785        <li>
786    <a class='dropdown-item' href='/contribute/05_reference'>
787 <span class="dropdown-text">Test class reference</span></a>
788  </li>  
789        <li>
790    <a class='dropdown-item' href='/contribute/06_automated_code_and_ai'>
791 <span class="dropdown-text">Automated Code and AI</span></a>
792  </li>  
793    </ul>
794  </li>
795</ul>
796          </div> <!-- /navcollapse -->
797            <div class="quarto-navbar-tools">
798    <div class="dropdown">
799      <a href="" title="" id="quarto-navigation-tool-dropdown-0" class="quarto-navigation-tool dropdown-toggle px-1" data-bs-toggle="dropdown" aria-expanded="false" role="link" aria-label=""><i class="bi bi-github"></i></a>
800      <ul class="dropdown-menu" aria-labelledby="quarto-navigation-tool-dropdown-0">
801          <li>
802            <a class="dropdown-item quarto-navbar-tools-item" href="https://github.com/ibis-project/ibis">
803            Source code
804            </a>
805          </li>
806          <li>
807            <a class="dropdown-item quarto-navbar-tools-item" href="https://github.com/ibis-project/ibis/issues/new?assignees=&amp;labels=bug&amp;projects=&amp;template=bug-report.yml&amp;title=bug">
808            Report a bug
809            </a>
810          </li>
811          <li>
812            <a class="dropdown-item quarto-navbar-tools-item" href="https://github.com/ibis-project/ibis/issues/new?assignees=&amp;labels=docs&amp;projects=&amp;template=docs-issue.yml&amp;title=docs">
813            Report a documentation issue
814            </a>
815          </li>
816          <li>
817            <a class="dropdown-item quarto-navbar-tools-item" href="https://github.com/ibis-project/ibis/issues/new?assignees=&amp;labels=feature&amp;projects=&amp;template=feature-request.yml&amp;title=feat">
818            Submit a feature request
819            </a>
820          </li>
821          <li>
822            <a class="dropdown-item quarto-navbar-tools-item" href="https://github.com/ibis-project/ibis/discussions/new?category=q-a">
823            Ask the community for help
824            </a>
825          </li>
826      </ul>
827    </div>
828  <a href="" class="quarto-color-scheme-toggle quarto-navigation-tool  px-1" onclick="window.quartoToggleColorScheme(); return false;" title="Toggle dark mode"><i class="bi"></i></a>
829</div>
830      </div> <!-- /container-fluid -->
831    </nav>
832</header>
833<!-- content -->
834<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
835<!-- sidebar -->
836<!-- margin-sidebar -->
837    
838<!-- main -->
839<main class="content page-columns page-full" id="quarto-document-content">
840
841
842
843
844
845<div class="quarto-about-jolla">
846  <img src="logo.svg" class="about-image
847  round " style="height: 15em; width: 15em;">
848 <header id="title-block-header" class="quarto-title-block default">
849<div class="quarto-title">
850<h1 class="title">Ibis</h1>
851</div>
852<div>
853  <div class="description">
854    the portable Python dataframe library
855  </div>
856</div>
857<div class="quarto-title-meta">
858  </div>
859</header><div id="about">
860</div> 
861  <hr class="about-sep">
862   <div class="about-links">
863  <a class='about-link' href='/why' rel target>
864    <i class="bi bi-info-circle"></i>
865     <span class="about-link-text">Why Ibis?</span>
866  </a>
867  <a class='about-link' href='/install' rel target>
868    <i class="bi bi-download"></i>
869     <span class="about-link-text">Installation</span>
870  </a>
871  <a class='about-link' href='/tutorials/basics' rel target>
872    <i class="bi bi-book"></i>
873     <span class="about-link-text">10 minutes to Ibis</span>
874  </a>
875  <a class='about-link' href='/posts' rel target>
876    <i class="bi bi-postcard"></i>
877     <span class="about-link-text">Blog</span>
878  </a>
879  <a href="https://github.com/ibis-project" class="about-link" rel="" target="">
880    <i class="bi bi-github"></i>
881     <span class="about-link-text">GitHub</span>
882  </a>
883  <a href="https://ibis-project.zulipchat.com" class="about-link" rel="" target="">
884    <i class="bi bi-zulip"></i>
885     <span class="about-link-text">Chat</span>
886  </a>
887  <a href="https://ibis-project.org/posts.xml" class="about-link" rel="" target="">
888    <i class="bi bi-rss"></i>
889     <span class="about-link-text">RSS</span>
890  </a>
891</div>
892</div>
893
894<div style="page-break-after: always;"></div>
895<div class="column-page">
896<section id="an-open-source-dataframe-library-that-works-with-any-data-system" class="level3">
897<h3 data-anchor-id="an-open-source-dataframe-library-that-works-with-any-data-system">An open source dataframe library that works with any data system</h3>
898<ul>
899<li>Use the same API for more than 20 backends</li>
900<li>Fast local dataframes with embedded DuckDB (default), Polars, or DataFusion</li>
901<li>Iterate locally and deploy remotely by changing a single line of code</li>
902<li>Compose SQL and Python dataframe code, bridging the gap between data engineering and data science</li>
903</ul>
904</section>
905<section id="ibis-the-portable-python-dataframe-library" class="level2">
906<h2 data-anchor-id="ibis-the-portable-python-dataframe-library">Ibis: the portable Python dataframe library</h2>
907<p>Ibis offers a familiar local dataframe experience with outstanding performance, using <a href="https://duckdb.org">DuckDB</a> by default.</p>
908<div id="0c271863" class="cell" data-execution_count="2">
909<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="annotated-cell-1"><pre class="sourceCode python code-annotation-code code-with-copy code-annotated"><code class="sourceCode python"><button class="code-annotation-anchor" data-target-cell="annotated-cell-1" data-target-annotation="1">1</button><span id="annotated-cell-1-1" class="code-annotation-target"><a href="#annotated-cell-1-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> ibis</span>
910<span id="annotated-cell-1-2"><a href="#annotated-cell-1-2" aria-hidden="true" tabindex="-1"></a></span>
911<button class="code-annotation-anchor" data-target-cell="annotated-cell-1" data-target-annotation="2">2</button><span id="annotated-cell-1-3" class="code-annotation-target"><a href="#annotated-cell-1-3" aria-hidden="true" tabindex="-1"></a>ibis.options.interactive <span class="op">=</span> <span class="va">True</span></span>
912<span id="annotated-cell-1-4"><a href="#annotated-cell-1-4" aria-hidden="true" tabindex="-1"></a></span>
913<button class="code-annotation-anchor" data-target-cell="annotated-cell-1" data-target-annotation="3">3</button><span id="annotated-cell-1-5" class="code-annotation-target"><a href="#annotated-cell-1-5" aria-hidden="true" tabindex="-1"></a>t <span class="op">=</span> ibis.read_parquet(<span class="st">"penguins.parquet"</span>, table_name<span class="op">=</span><span class="st">"penguins"</span>)</span>
914<button class="code-annotation-anchor" data-target-cell="annotated-cell-1" data-target-annotation="4">4</button><span id="annotated-cell-1-6" class="code-annotation-target"><a href="#annotated-cell-1-6" aria-hidden="true" tabindex="-1"></a>t.head(<span class="dv">3</span>)</span><div class="code-annotation-gutter-bg"></div><div class="code-annotation-gutter"></div></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
915<div class="cell-annotation">
916<dl class="code-annotation-container-hidden code-annotation-container-grid">
917<dt data-target-cell="annotated-cell-1" data-target-annotation="1">1</dt>
918<dd>
919<span data-code-cell="annotated-cell-1" data-code-lines="1" data-code-annotation="1">Import Ibis.</span>
920</dd>
921<dt data-target-cell="annotated-cell-1" data-target-annotation="2">
9212</dt>
922<dd>
923<span data-code-cell="annotated-cell-1" data-code-lines="3" data-code-annotation="2">Enable interactive mode for exploratory data analysis (EDA) or demos.</span>
924</dd>
925<dt data-target-cell="annotated-cell-1" data-target-annotation="3">3</dt>
926<dd>
927<span data-code-cell="annotated-cell-1" data-code-lines="5" data-code-annotation="3">Read a Parquet file and specify a table name (optional).</span>
928</dd>
929<dt data-target-cell="annotated-cell-1" data-target-annotation="4">4</dt>
930<dd>
931<span data-code-cell="annotated-cell-1" data-code-lines="6" data-code-annotation="4">Display the first few rows of the table.</span>
932</dd>
933</dl>
934</div>
935<div class="cell-output cell-output-display" data-execution_count="2">
936<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓
937┃<span style="font-weight: bold"> species </span>┃<span style="font-weight: bold"> island    </span>┃<span style="font-weight: bold"> bill_length_mm </span>┃<span style="font-weight: bold"> bill_depth_mm </span>┃<span style="font-weight: bold"> flipper_length_mm </span>┃<span style="font-weight: bold"> body_mass_g </span>┃<span style="font-weight: bold"> sex    </span>┃<span style="font-weight: bold"> year  </span>┃
938┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩
939│ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>  │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">float64</span>        │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">float64</span>       │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span>             │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span>       │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span> │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span> │
940├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┤
941│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">39.1</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">18.7</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">181</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3750</span> │ <span style="color: #008000; text-decoration-color: #008000">male  </span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
942│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">39.5</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">17.4</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">186</span>
942 │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3800</span> │ <span style="color: #008000; text-decoration-color: #008000">female</span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
943│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">40.3</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">18.0</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">195</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3250</span> │ <span style="color: #008000; text-decoration-color: #008000">female</span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
944└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┘
945</pre>
946</div>
947</div>
948<p>Iterate and explore data locally:</p>
949<div id="fe50773d" class="cell" data-execution_count="3">
950<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="annotated-cell-2"><pre class="sourceCode python code-annotation-code code-with-copy code-annotated"><code class="sourceCode python"><button class="code-annotation-anchor" data-target-cell="annotated-cell-2" data-target-annotation="1">1</button><span id="annotated-cell-2-1" class="code-annotation-target"><a href="#annotated-cell-2-1" aria-hidden="true" tabindex="-1"></a>grouped <span class="op">=</span> t.group_by(<span class="st">"species"</span>, <span class="st">"island"</span>).agg(count<span class="op">=</span>t.count()).order_by(<span class="st">"count"</span>)</span>
951<button class="code-annotation-anchor" data-target-cell="annotated-cell-2" data-target-annotation="2">2</button><span id="annotated-cell-2-2" class="code-annotation-target"><a href="#annotated-cell-2-2" aria-hidden="true" tabindex="-1"></a>grouped</span><div class="code-annotation-gutter-bg"></div><div class="code-annotation-gutter"></div></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
952<div class="cell-annotation">
953<dl class="code-annotation-container-hidden code-annotation-container-grid">
954<dt data-target-cell="annotated-cell-2" data-target-annotation="1">1</dt>
955<dd>
956<span data-code-cell="annotated-cell-2" data-code-lines="1" data-code-annotation="1">Transform the table.</span>
957</dd>
958<dt data-target-cell="annotated-cell-2" data-target-annotation="2">2</dt>
959<dd>
960<span data-code-cell="annotated-cell-2" data-code-lines="2" data-code-annotation="2">Display the transformed table.</span>
961</dd>
962</dl>
963</div>
964<div class="cell-output cell-output-display" data-execution_count="3">
965<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓
966┃<span style="font-weight: bold"> species   </span>┃<span style="font-weight: bold"> island    </span>┃<span style="font-weight: bold"> count </span>┃
967┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩
968│ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span> │
969├───────────┼───────────┼───────┤
970│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Biscoe   </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">44</span> │
971│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">52</span> │
972│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Dream    </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">56</span> │
973│ <span style="color: #008000; text-decoration-color: #008000">Chinstrap</span> │ <span style="color: #008000; text-decoration-color: #008000">Dream    </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">68</span> │
974│ <span style="color: #008000; text-decoration-color: #008000">Gentoo   </span> │ <span style="color: #008000; text-decoration-color: #008000">Biscoe   </span> │   <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">124</span> │
975└───────────┴───────────┴───────┘
976</pre>
977</div>
978</div>
979<section id="one-api-for-more-than-20-backends" class="level3">
980<h3 data-anchor-id="one-api-for-more-than-20-backends">One API for more than 20 backends</h3>
981<p>Use the same dataframe API for more than 20 backends:</p>
982<div id="feb1dc8b" class="cell" data-execution_count="4">
983<div class="cell-output cell-output-display">
984<div>            
984<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_SVG"></script>
984<script type="text/javascript">if (window.MathJax && window.MathJax.Hub && window.MathJax.Hub.Config) {window.MathJax.Hub.Config({SVG: {font: "STIX-Web"}});}</script>
984                
984<script type="text/javascript">window.PlotlyConfig = {MathJaxConfig: 'local'};</script>
984
985        
985<script charset="utf-8" src="https://cdn.plot.ly/plotly-3.3.1.min.js" integrity="sha256-4rD3fugVb/nVJYUv5Ky3v+fYXoouHaBSP20WIJuEiWg=" crossorigin="anonymous"></script>
985                <div id="fb294195-8e71-4ae8-a29d-891d1dc594d5" class="plotly-graph-div" style="height:525px; width:100%;"></div>            
985<script type="text/javascript">                window.PLOTLYENV=window.PLOTLYENV || {};                                if (document.getElementById("fb294195-8e71-4ae8-a29d-891d1dc594d5")) {                    Plotly.newPlot(                        "fb294195-8e71-4ae8-a29d-891d1dc594d5",                        [{"link":{"color":["#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#758da4","#aa8179","#aa8179"],"line":{"color":"grey","width":0.5},"source":[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,23],"target":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],"value":[21,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]},"node":{"color":["#7C65A0","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#6A9BC9","#D58273","#D58273"],"label":["Ibis API","SQL","Athena","BigQuery","ClickHouse","Databricks","DataFusion","Druid","DuckDB","Exasol","Flink","Impala","Materialize","MSSQL","MySQL","Oracle","PostgreSQL","PySpark","RisingWave","SingleStoreDB","Snowflake","SQLite","Trino","DataFrame","Polars"],"line":{"color":"grey","width":0.5},"pad":20,"thickness":20},"type":"sankey"}],                        {"template":{"data":{"barpolar":[{"marker":{"line":{"color":"rgb(17,17,17)","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"bar":[{"error_x":{"color":"#f2f5fa"},"error_y":{"color":"#f2f5fa"},"marker":{"line":{"color":"rgb(17,17,17)","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"carpet":[{"aaxis":{"endlinecolor":"#A2B1C6","gridcolor":"#506784","linecolor":"#506784","minorgridcolor":"#506784","startlinecolor":"#A2B1C6"},"baxis":{"endlinecolor":"#A2B1C6","gridcolor":"#506784","linecolor":"#506784","minorgridcolor":"#506784","startlinecolor":"#A2B1C6"},"type":"carpet"}],"choropleth":[{"colorbar":{"outlinewidth":0,"ticks":""},"type":"choropleth"}],"contourcarpet":[{"colorbar":{"outlinewidth":0,"ticks":""},"type":"contourcarpet"}],"contour":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"type":"contour"}],"heatmap":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"type":"heatmap"}],"histogram2dcontour":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"type":"histogram2dcontour"}],"histogram2d":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"type":"histogram2d"}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"mesh3d":[{"colorbar":{"outlinewidth":0,"ticks":""},"type":"mesh3d"}],"parcoords":[{"line":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"parcoords"}],"pie":[{"automargin":true,"type":"pie"}],"scatter3d":[{"line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatter3d"}],"scattercarpet":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattercarpet"}],"scattergeo":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattergeo"}],"scattergl":[{"marker":{"line":{"color":"#283442"}},"type":"scattergl"}],"scattermapbox":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattermapbox"}],"scattermap":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattermap"}],"scatterpolargl":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatterpolargl"}],"scatterpolar":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatterpolar"}],"scatter":[{"marker":{"line":{"color":"#283442"}},"type":"scatter"}],"scatterternary":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatterternary"}],"surface":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"type":"surface"}],"table":[{"cells":{"fill":{"color":"#506784"},"line":{"color":"rgb(17,17,17)"}},"header":{"fill":{"color":"#2a3f5f"},"line":{"color":"rgb(17,17,17)"}},"type":"table"}]},"layout":{"annotationdefaults":{"arrowcolor":"#f2f5fa","arrowhead":0,"arrowwidth":1},"autotypenumbers":"strict","coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]],"sequential":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"sequentialminus":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]},"colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#f2f5fa"},"geo":{"bgcolor":"rgb(17,17,17)","lakecolor":"rgb(17,17,17)","landcolor":"rgb(17,17,17)","showlakes":true,"showland":true,"subunitcolor":"#506784"},"hoverlabel":{"align":"left"},"hovermode":"closest","mapbox":{"style":"dark"},"margin":{"b":0,"l":0,"r":0,"t":30},"paper_bgcolor":"rgb(17,17,17)","plot_bgcolor":"rgb(17,17,17)","polar":{"angularaxis":{"gridcolor":"#506784","linecolor":"#506784","ticks":""},"bgcolor":"rgb(17,17,17)","radialaxis":{"gridcolor":"#506784","linecolor":"#506784","ticks":""}},"scene":{"xaxis":{"backgroundcolor":"rgb(17,17,17)","gridcolor":"#506784","gridwidth":2,"linecolor":"#506784","showbackground":true,"ticks":"","zerolinecolor":"#C8D4E3"},"yaxis":{"backgroundcolor":"rgb(17,17,17)","gridcolor":"#506784","gridwidth":2,"linecolor":"#506784","showbackground":true,"ticks":"","zerolinecolor":"#C8D4E3"},"zaxis":{"backgroundcolor":"rgb(17,17,17)","gridcolor":"#506784","gridwidth":2,"linecolor":"#506784","showbackground":true,"ticks":"","zerolinecolor":"#C8D4E3"}},"shapedefaults":{"line":{"color":"#f2f5fa"}},"sliderdefaults":{"bgcolor":"#C8D4E3","bordercolor":"rgb(17,17,17)","borderwidth":1,"tickwidth":0},"ternary":{"aaxis":{"gridcolor":"#506784","linecolor":"#506784","ticks":""},"baxis":{"gridcolor":"#506784","linecolor":"#506784","ticks":""},"bgcolor":"rgb(17,17,17)","caxis":{"gridcolor":"#506784","linecolor":"#506784","ticks":""}},"title":{"x":0.05},"updatemenudefaults":{"bgcolor":"#506784","borderwidth":0},"xaxis":{"automargin":true,"gridcolor":"#283442","linecolor":"#506784","ticks":"","title":{"standoff":15},"zerolinecolor":"#283442","zerolinewidth":2},"yaxis":{"automargin":true,"gridcolor":"#283442","linecolor":"#506784","ticks":"","title":{"standoff":15},"zerolinecolor":"#283442","zerolinewidth":2}}},"title":{"font":{"size":30},"text":"Ibis backend types"},"font":{"size":20},"margin":{"l":30,"r":30,"t":80,"b":30}},                        {"responsive": true}                    ).then(function(){
986                            
987var gd = document.getElementById('fb294195-8e71-4ae8-a29d-891d1dc594d5');
988var x = new MutationObserver(function (mutations, observer) {{
989        var display = window.getComputedStyle(gd).display;
990        if (!display || display === 'none') {{
991            console.log([gd, 'removed!']);
992            Plotly.purge(gd);
993            observer.disconnect();
994        }}
995}});
996
997// Listen for the removal of the full notebook cells
998var notebookContainer = gd.closest('#notebook-container');
999if (notebookContainer) {{
1000    x.observe(notebookContainer, {childList: true});
1001}}
1002
1003// Listen for the clearing of the current output cell
1004var outputEl = gd.closest('.output');
1005if (outputEl) {{
1006    x.observe(outputEl, {childList: true});
1007}}
1008
1009                        })                };            </script>
1009        </div>
1010</div>
1011</div>
1012<p>For example:</p>
1013<div class="tabset-margin-container"></div><div class="panel-tabset">
1014<ul class="nav nav-tabs" role="tablist"><li class="nav-item" role="presentation"><a class="nav-link active" id="tabset-1-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-1-1" role="tab" aria-controls="tabset-1-1" aria-selected="true" href="">DuckDB</a></li><li class="nav-item" role="presentation"><a class="nav-link" id="tabset-1-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-1-2" role="tab" aria-controls="tabset-1-2" aria-selected="false" href="">Polars</a></li><li class="nav-item" role="presentation"><a class="nav-link" id="tabset-1-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-1-3" role="tab" aria-controls="tabset-1-3" aria-selected="false" href="">DataFusion</a></li><li class="nav-item" role="presentation"><a class="nav-link" id="tabset-1-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-1-4" role="tab" aria-controls="tabset-1-4" aria-selected="false" href="">PySpark</a></li></ul>
1015<div class="tab-content">
1016<div id="tabset-1-1" class="tab-pane active" role="tabpanel" aria-labelledby="tabset-1-1-tab">
1017<div id="2bf4ea2f" class="cell" data-execution_count="5">
1018<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>con <span class="op">=</span> ibis.<span class="ex">connect</span>(<span class="st">"duckdb://"</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1019</div>
1020<div id="4ca6d351" class="cell" data-execution_count="6">
1021<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>t <span class="op">=</span> con.read_parquet(<span class="st">"penguins.parquet"</span>)</span>
1022<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>t.head(<span class="dv">3</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1023<div class="cell-output cell-output-display" data-execution_count="6">
1024<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓
1025┃<span style="font-weight: bold"> species </span>┃<span style="font-weight: bold"> island    </span>┃<span style="font-weight: bold"> bill_length_mm </span>┃<span style="font-weight: bold"> bill_depth_mm </span>┃<span style="font-weight: bold"> flipper_length_mm </span>┃<span style="font-weight: bold"> body_mass_g </span>┃<span style="font-weight: bold"> sex    </span>┃<span style="font-weight: bold"> year  </span>┃
1026┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩
1027│ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>  │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">float64</span>        │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">float64</span>       │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span>             │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span>       │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span> │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span> │
1028├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┤
1029│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span>
1029 │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">39.1</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">18.7</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">181</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3750</span> │ <span style="color: #008000; text-decoration-color: #008000">male  </span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
1030│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">39.5</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">17.4</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">186</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3800</span> │ <span style="color: #008000; text-decoration-color: #008000">female</span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
1031│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">40.3</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">18.0</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">195</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3250</span> │ <span style="color: #008000; text-decoration-color: #008000">female</span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
1032└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┘
1033</pre>
1034</div>
1035</div>
1036<div id="10932502" class="cell" data-execution_count="7">
1037<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>t.group_by(<span class="st">"species"</span>, <span class="st">"island"</span>).agg(count<span class="op">=</span>t.count()).order_by(<span class="st">"count"</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1038<div class="cell-output cell-output-display" data-execution_count="7">
1039<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓
1040┃<span style="font-weight: bold"> species   </span>┃<span style="font-weight: bold"> island    </span>┃<span style="font-weight: bold"> count </span>┃
1041┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩
1042│ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span> │
1043├───────────┼───────────┼───────┤
1044│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Biscoe   </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">44</span> │
1045│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">52</span> │
1046│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Dream    </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">56</span> │
1047│ <span style="color: #008000; text-decoration-color: #008000">Chinstrap</span> │ <span style="color: #008000; text-decoration-color: #008000">Dream    </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">68</span> │
1048│ <span style="color: #008000; text-decoration-color: #008000">Gentoo   </span> │ <span style="color: #008000; text-decoration-color: #008000">Biscoe   </span> │   <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">124</span> │
1049└───────────┴───────────┴───────┘
1050</pre>
1051</div>
1052</div>
1053</div>
1054<div id="tabset-1-2" class="tab-pane" role="tabpanel" aria-labelledby="tabset-1-2-tab">
1055<div id="8a510570" class="cell" data-execution_count="8">
1056<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>con <span class="op">=</span> ibis.<span class="ex">connect</span>(<span class="st">"polars://"</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1057</div>
1058<div id="fce7d258" class="cell" data-execution_count="9">
1059<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>t <span class="op">=</span> con.read_parquet(<span class="st">"penguins.parquet"</span>)</span>
1060<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>t.head(<span class="dv">3</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1061<div class="cell-output cell-output-display" data-execution_count="9">
1062<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓
1063┃<span style="font-weight: bold">
1063 species </span>┃<span style="font-weight: bold"> island    </span>┃<span style="font-weight: bold"> bill_length_mm </span>┃<span style="font-weight: bold"> bill_depth_mm </span>┃<span style="font-weight: bold"> flipper_length_mm </span>┃<span style="font-weight: bold"> body_mass_g </span>┃<span style="font-weight: bold"> sex    </span>┃<span style="font-weight: bold"> year  </span>┃
1064┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩
1065│ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>  │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">float64</span>        │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">float64</span>       │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span>             │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span>       │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span> │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span> │
1066├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┤
1067│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">39.1</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">18.7</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">181</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3750</span> │ <span style="color: #008000; text-decoration-color: #008000">male  </span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
1068│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">39.5</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">17.4</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">186</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3800</span> │ <span style="color: #008000; text-decoration-color: #008000">female</span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
1069│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">40.3</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">18.0</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">195</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3250</span> │ <span style="color: #008000; text-decoration-color: #008000">female</span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
1070└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┘
1071</pre>
1072</div>
1073</div>
1074<div id="69049977" class="cell" data-execution_count="10">
1075<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>t.group_by(<span class="st">"species"</span>, <span class="st">"island"</span>).agg(count<span class="op">=</span>t.count()).order_by(<span class="st">"count"</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1076<div class="cell-output cell-output-display" data-execution_count="10">
1077<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓
1078┃<span style="font-weight: bold"> species   </span>┃<span style="font-weight: bold"> island    </span>┃<span style="font-weight: bold"> count </span>┃
1079┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩
1080│ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span> │
1081├───────────┼───────────┼───────┤
1082│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Biscoe   </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">44</span> │
1083│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">52</span> │
1084│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Dream    </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">56</span> │
1085│ <span style="color: #008000; text-decoration-color: #008000">Chinstrap</span> │ <span style="color: #008000; text-decoration-color: #008000">Dream    </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">68</span> │
1086│ <span style="color: #008000; text-decoration-color: #008000">Gentoo   </span> │ <span style="color: #008000; text-decoration-color: #008000">Biscoe   </span> │   <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">124</span> │
1087└───────────┴───────────┴───────┘
1088</pre>
1089</div>
1090</div>
1091</div>
1092<div id="tabset-1-3" class="tab-pane" role="tabpanel" aria-labelledby="tabset-1-3-tab">
1093<div id="437cb990" class="cell" data-execution_count="11">
1094<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>con <span class="op">=</span> ibis.<span class="ex">connect</span>(<span class="st">"datafusion://"</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1095</div>
1096<div id="47363e33" class="cell" data-execution_count="12">
1097<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>t <span class="op">=</span> con.read_parquet(<span class="st">"penguins.parquet"</span>)</span>
1098<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>t.head(<span class="dv">3</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1099<div class="cell-output cell-output-display" data-execution_count="12">
1100<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓
1101┃<span style="font-weight: bold">
1101 species </span>┃<span style="font-weight: bold"> island    </span>┃<span style="font-weight: bold"> bill_length_mm </span>┃<span style="font-weight: bold"> bill_depth_mm </span>┃<span style="font-weight: bold"> flipper_length_mm </span>┃<span style="font-weight: bold"> body_mass_g </span>┃<span style="font-weight: bold"> sex    </span>┃<span style="font-weight: bold"> year  </span>┃
1102┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩
1103│ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>  │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">float64</span>        │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">float64</span>       │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span>             │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span>       │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span> │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span> │
1104├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┤
1105│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">39.1</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">18.7</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">181</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3750</span> │ <span style="color: #008000; text-decoration-color: #008000">male  </span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
1106│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">39.5</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">17.4</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">186</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3800</span> │ <span style="color: #008000; text-decoration-color: #008000">female</span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
1107│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">40.3</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">18.0</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">195</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3250</span> │ <span style="color: #008000; text-decoration-color: #008000">female</span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
1108└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┘
1109</pre>
1110</div>
1111</div>
1112<div id="aae10640" class="cell" data-execution_count="13">
1113<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>t.group_by(<span class="st">"species"</span>, <span class="st">"island"</span>).agg(count<span class="op">=</span>t.count()).order_by(<span class="st">"count"</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1114<div class="cell-output cell-output-display" data-execution_count="13">
1115<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓
1116┃<span style="font-weight: bold"> species   </span>┃<span style="font-weight: bold"> island    </span>┃<span style="font-weight: bold"> count </span>┃
1117┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩
1118│ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span> │
1119├───────────┼───────────┼───────┤
1120│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Biscoe   </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">44</span> │
1121│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">52</span> │
1122│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Dream    </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">56</span> │
1123│ <span style="color: #008000; text-decoration-color: #008000">Chinstrap</span> │ <span style="color: #008000; text-decoration-color: #008000">Dream    </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">68</span> │
1124│ <span style="color: #008000; text-decoration-color: #008000">Gentoo   </span> │ <span style="color: #008000; text-decoration-color: #008000">Biscoe   </span> │   <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">124</span> │
1125└───────────┴───────────┴───────┘
1126</pre>
1127</div>
1128</div>
1129</div>
1130<div id="tabset-1-4" class="tab-pane" role="tabpanel" aria-labelledby="tabset-1-4-tab">
1131<div id="b0b98be0" class="cell" data-execution_count="14">
1132<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>con <span class="op">=</span> ibis.<span class="ex">connect</span>(<span class="st">"pyspark://"</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1133</div>
1134<div id="4bff712c" class="cell" data-execution_count="15">
1135<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>t <span class="op">=</span> con.read_parquet(<span class="st">"penguins.parquet"</span>)</span>
1136<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>t.head(<span class="dv">3</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1137<div class="cell-output cell-output-display" data-execution_count="15">
1138<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓
1139┃<span style="font-weight: bold">
1139 species </span>┃<span style="font-weight: bold"> island    </span>┃<span style="font-weight: bold"> bill_length_mm </span>┃<span style="font-weight: bold"> bill_depth_mm </span>┃<span style="font-weight: bold"> flipper_length_mm </span>┃<span style="font-weight: bold"> body_mass_g </span>┃<span style="font-weight: bold"> sex    </span>┃<span style="font-weight: bold"> year  </span>┃
1140┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩
1141│ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>  │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">float64</span>        │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">float64</span>       │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span>             │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span>       │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span> │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span> │
1142├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┤
1143│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">39.1</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">18.7</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">181</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3750</span> │ <span style="color: #008000; text-decoration-color: #008000">male  </span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
1144│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">39.5</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">17.4</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">186</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3800</span> │ <span style="color: #008000; text-decoration-color: #008000">female</span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
1145│ <span style="color: #008000; text-decoration-color: #008000">Adelie </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │           <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">40.3</span> │          <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">18.0</span> │               <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">195</span> │        <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">3250</span> │ <span style="color: #008000; text-decoration-color: #008000">female</span> │  <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2007</span> │
1146└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┘
1147</pre>
1148</div>
1149</div>
1150<div id="4409f194" class="cell" data-execution_count="16">
1151<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>t.group_by(<span class="st">"species"</span>, <span class="st">"island"</span>).agg(count<span class="op">=</span>t.count()).order_by(<span class="st">"count"</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1152<div class="cell-output cell-output-display" data-execution_count="16">
1153<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓
1154┃<span style="font-weight: bold"> species   </span>┃<span style="font-weight: bold"> island    </span>┃<span style="font-weight: bold"> count </span>┃
1155┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩
1156│ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span> │
1157├───────────┼───────────┼───────┤
1158│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Biscoe   </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">44</span> │
1159│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">52</span> │
1160│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Dream    </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">56</span> │
1161│ <span style="color: #008000; text-decoration-color: #008000">Chinstrap</span> │ <span style="color: #008000; text-decoration-color: #008000">Dream    </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">68</span> │
1162│ <span style="color: #008000; text-decoration-color: #008000">Gentoo   </span> │ <span style="color: #008000; text-decoration-color: #008000">Biscoe   </span> │   <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">124</span> │
1163└───────────┴───────────┴───────┘
1164</pre>
1165</div>
1166</div>
1167</div>
1168</div>
1169</div>
1170<p>This allows you to iterate locally and deploy remotely by changing a single line of code. For instance, develop locally with DuckDB and deploy remotely to BigQuery. Or, using any combination of backends that meet your requirements.</p>
1171</section>
1172<section id="python-sql-better-together" class="level3">
1173<h3 data-anchor-id="python-sql-better-together">Python + SQL: better together</h3>
1174<p>Ibis works by decoupling the dataframe API from the backend execution. Most backends support a SQL dialect, which Ibis compiles its expressions into using <a href="https://github.com/tobymao/sqlglot">SQLGlot</a>. You can inspect the SQL that Ibis generates for any SQL backend:</p>
1175<div id="a15502bb" class="cell" data-execution_count="17">
1176<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="annotated-cell-3"><pre class="sourceCode python code-annotation-code code-with-copy code-annotated"><code class="sourceCode python"><button class="code-annotation-anchor" data-target-cell="annotated-cell-3" data-target-annotation="1">1</button><span id="annotated-cell-3-1" class="code-annotation-target"><a href="#annotated-cell-3-1" aria-hidden="true" tabindex="-1"></a>ibis.to_sql(grouped)</span><div class="code-annotation-gutter-bg"></div><div class="code-annotation-gutter"></div></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1177<div class="cell-annotation">
1178<dl class="code-annotation-container-hidden code-annotation-container-grid">
1179<dt data-target-cell="annotated-cell-3" data-target-annotation="1">1</dt>
1180<dd>
1181<span data-code-cell="annotated-cell-3" data-code-lines="1" data-code-annotation="1">Display the SQL generated from the table expression.</span>
1182</dd>
1183</dl>
1184</div>
1185<div class="cell-output cell-output-display cell-output-markdown" data-execution_count="17">
1186<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">SELECT</span></span>
1187<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">*</span></span>
1188<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="kw">FROM</span> (</span>
1189<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">SELECT</span></span>
1190<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    <span class="ot">
1190"t0"</span>.<span class="ot">"species"</span>,</span>
1191<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>    <span class="ot">"t0"</span>.<span class="ot">"island"</span>,</span>
1192<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    <span class="fu">COUNT</span>(<span class="op">*</span>) <span class="kw">AS</span> <span class="ot">"count"</span></span>
1193<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">FROM</span> <span class="ot">"penguins"</span> <span class="kw">AS</span> <span class="ot">"t0"</span></span>
1194<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">GROUP</span> <span class="kw">BY</span></span>
1195<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>    <span class="dv">1</span>,</span>
1196<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>    <span class="dv">2</span></span>
1197<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>) <span class="kw">AS</span> <span class="ot">"t1"</span></span>
1198<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a><span class="kw">ORDER</span> <span class="kw">BY</span></span>
1199<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>  <span class="ot">"t1"</span>.<span class="ot">"count"</span> <span class="kw">ASC</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1200</div>
1201</div>
1202<p>And use SQL strings directly, mixing and matching with Python dataframe code:</p>
1203<div id="81a157fe" class="cell" data-execution_count="19">
1204<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="annotated-cell-4"><pre class="sourceCode python code-annotation-code code-with-copy code-annotated"><code class="sourceCode python"><button class="code-annotation-anchor" data-target-cell="annotated-cell-4" data-target-annotation="1">1</button><span id="annotated-cell-4-1" class="code-annotation-target"><a href="#annotated-cell-4-1" aria-hidden="true" tabindex="-1"></a>t.sql(</span>
1205<span id="annotated-cell-4-2"><a href="#annotated-cell-4-2" aria-hidden="true" tabindex="-1"></a>    <span class="st">"SELECT species, island, COUNT(*) AS count FROM penguins GROUP BY species, island"</span></span>
1206<button class="code-annotation-anchor" data-target-cell="annotated-cell-4" data-target-annotation="2">2</button><span id="annotated-cell-4-3" class="code-annotation-target"><a href="#annotated-cell-4-3" aria-hidden="true" tabindex="-1"></a>).order_by(<span class="st">"count"</span>)</span><div class="code-annotation-gutter-bg"></div><div class="code-annotation-gutter"></div></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
1207<div class="cell-annotation">
1208<dl class="code-annotation-container-hidden code-annotation-container-grid">
1209<dt data-target-cell="annotated-cell-4" data-target-annotation="1">1</dt>
1210<dd>
1211<span data-code-cell="annotated-cell-4" data-code-lines="1,2" data-code-annotation="1">Transform the table using SQL.</span>
1212</dd>
1213<dt data-target-cell="annotated-cell-4" data-target-annotation="2">2</dt>
1214<dd>
1215<span data-code-cell="annotated-cell-4" data-code-lines="3" data-code-annotation="2">
1215Then, transform the table using Python dataframe code.</span>
1216</dd>
1217</dl>
1218</div>
1219<div class="cell-output cell-output-display" data-execution_count="19">
1220<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓
1221┃<span style="font-weight: bold"> species   </span>┃<span style="font-weight: bold"> island    </span>┃<span style="font-weight: bold"> count </span>┃
1222┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩
1223│ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">string</span>    │ <span style="color: #7f7f7f; text-decoration-color: #7f7f7f">int64</span> │
1224├───────────┼───────────┼───────┤
1225│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Biscoe   </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">44</span> │
1226│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Torgersen</span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">52</span> │
1227│ <span style="color: #008000; text-decoration-color: #008000">Adelie   </span> │ <span style="color: #008000; text-decoration-color: #008000">Dream    </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">56</span> │
1228│ <span style="color: #008000; text-decoration-color: #008000">Chinstrap</span> │ <span style="color: #008000; text-decoration-color: #008000">Dream    </span> │    <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">68</span> │
1229│ <span style="color: #008000; text-decoration-color: #008000">Gentoo   </span> │ <span style="color: #008000; text-decoration-color: #008000">Biscoe   </span> │   <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">124</span> │
1230└───────────┴───────────┴───────┘
1231</pre>
1232</div>
1233</div>
1234<p>This allows you to combine the flexibility of Python with the scale and performance of modern SQL.</p>
1235</section>
1236</section>
1237<section id="users-say" class="level2 text-center">
1238<h2 data-anchor-id="users-say">Users say…</h2>
1239</section>
1240<div class="index-grid">
1241<div class="index-g-col-4 card border-light mb-3 text-center">
1242<div class="card-body">
1243<p><span class="card-text">“Ibis is amazing, there is so much bikeshedding out there that this library improves upon. I love that now we can empower any visualization with nearly any dataset! Big thanks to those who have contributed!”</span></p>
1244<p><span class="blockquote-footer">Nick Shook</span></p>
1245</div>
1246</div>
1247<div class="index-g-col-4 card border-light mb-3 text-center">
1248<div class="card-body">
1249<p>“I now have Ibis code that runs PySpark in my Databricks environment and Polars on my laptop which is pretty slick 🔥”</p>
1250<p><span class="blockquote-footer">Mark Druffel</span></p>
1251</div>
1252</div>
1253<div class="index-g-col-4 card border-light mb-3 text-center">
1254<div class="card-body">
1255<p>“I love that with Ibis, I can use SQL for the heavy lifting or aggregations and then switch to a dataframe-like API for the type of dynamic transformations that would otherwise be tedious to do in pure SQL.”</p>
1256<p><span class="blockquote-footer">Daniel Kim</span></p>
1257</div>
1258</div>
1259</div>
1260<section id="get-started-with-ibis" class="level2 text-center">
1261<h2 data-anchor-id="get-started-with-ibis">Get started with Ibis</h2>
1262</section>
1263<div class="index-grid text-center">
1264<div class="index-g-col-4">
1265<p><a class='btn btn-primary w-100' href='/why'>Why Ibis?</a></p>
1266</div>
1267<div class="index-g-col-4">
1268<p><a class='btn btn-primary w-100' href='/tutorials/basics'>10 minutes to Ibis</a></p>
1269</div>
1270<div class="index-g-col-4">
1271<p><a href="./reference" class="btn btn-primary w-100">API reference</a></p>
1272</div>
1273</div>
1274</div>
1275
1276
1277
1278
1279<a onclick="window.scrollTo(0, 0); return false;" role="button" id="quarto-back-to-top"><i class="bi bi-arrow-up"></i> Back to top</a></main> <!-- /main -->
1280<script id="quarto-html-after-body" type="application/javascript">
1281  window.document.addEventListener("DOMContentLoaded", function (event) {
1282    // Ensure there is a toggle, if there isn't float one in the top right
1283    if (window.document.querySelector('.quarto-color-scheme-toggle') === null) {
1284      const a = window.document.createElement('a');
1285      a.classList.add('top-right');
1286      a.classList.add('quarto-color-scheme-toggle');
1287      a.href = "";
1288      a.onclick = function() { try { window.quartoToggleColorScheme(); } catch {} return false; };
1289      const i = window.document.createElement("i");
1290      i.classList.add('bi');
1291      a.appendChild(i);
1292      window.document.body.appendChild(a);
1293    }
1294    setColorSchemeToggle(hasAlternateSentinel())
1295    const isCodeAnnotation = (el) => {
1296      for (const clz of el.classList) {
1297        if (clz.startsWith('code-annotation-')) {                     
1298          return true;
1299        }
1300      }
1301      return false;
1302    }
1303    const onCopySuccess = function(e) {
1304      // button target
1305      const button = e.trigger;
1306      // don't keep focus
1307      button.blur();
1308      // flash "checked"
1309      button.classList.add('code-copy-button-checked');
1310      var currentTitle = button.getAttribute("title");
1311      button.setAttribute("title", "Copied!");
1312      let tooltip;
1313      if (window.bootstrap) {
1314        button.setAttribute("data-bs-toggle", "tooltip");
1315        button.setAttribute("data-bs-placement", "left");
1316        button.setAttribute("data-bs-title", "Copied!");
1317        tooltip = new bootstrap.Tooltip(button, 
1318          { trigger: "manual", 
1319            customClass: "code-copy-button-tooltip",
1320            offset: [0, -8]});
1321        tooltip.show();    
1322      }
1323      setTimeout(function() {
1324        if (tooltip) {
1325          tooltip.hide();
1326          button.removeAttribute("data-bs-title");
1327          button.removeAttribute("data-bs-toggle");
1328          button.removeAttribute("data-bs-placement");
1329        }
1330        button.setAttribute("title", currentTitle);
1331        button.classList.remove('code-copy-button-checked');
1332      }, 1000);
1333      // clear code selection
1334      e.clearSelection();
1335    }
1336    const getTextToCopy = function(trigger) {
1337      const outerScaffold = trigger.parentElement.cloneNode(true);
1338      const codeEl = outerScaffold.querySelector('code');
1339      for (const childEl of codeEl.children) {
1340        if (isCodeAnnotation(childEl)) {
1341          childEl.remove();
1342        }
1343      }
1344      return codeEl.innerText;
1345    }
1346    const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
1347      text: getTextToCopy
1348    });
1349    clipboard.on('success', onCopySuccess);
1350    if (window.document.getElementById('quarto-embedded-source-code-modal')) {
1351      const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
1352        text: getTextToCopy,
1353        container: window.document.getElementById('quarto-embedded-source-code-modal')
1354      });
1355      clipboardModal.on('success', onCopySuccess);
1356    }
1357      var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
1358      var mailtoRegex = new RegExp(/^mailto:/);
1359        var filterRegex = new RegExp("https:\/\/ibis-project\.org");
1360      var isInternal = (href) => {
1361          return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
1362      }
1363      // Inspect non-navigation links and adorn them if external
1364     var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
1365      for (var i=0; i<links.length; i++) {
1366        const link = links[i];
1367        if (!isInternal(link.href)) {
1368          // undo the damage that might have been done by quarto-nav.js in the case of
1369          // links that we want to consider external
1370          if (link.dataset.originalHref !== undefined) {
1371            link.href = link.dataset.originalHref;
1372          }
1373        }
1374      }
1375    function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
1376      const config = {
1377        allowHTML: true,
1378        maxWidth: 500,
1379        delay: 100,
1380        arrow: false,
1381        appendTo: function(el) {
1382            return el.parentElement;
1383        },
1384        interactive: true,
1385        interactiveBorder: 10,
1386        theme: 'quarto',
1387        placement: 'bottom-start',
1388      };
1389      if (contentFn) {
1390        config.content = contentFn;
1391      }
1392      if (onTriggerFn) {
1393        config.onTrigger = onTriggerFn;
1394      }
1395      if (onUntriggerFn) {
1396        config.onUntrigger = onUntriggerFn;
1397      }
1398      window.tippy(el, config); 
1399    }
1400    const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
1401    for (var i=0; i<noterefs.length; i++) {
1402      const ref = noterefs[i];
1403      tippyHover(ref, function() {
1404        // use id or data attribute instead here
1405        let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
1406        try { href = new URL(href).hash; } catch {}
1407        const id = href.replace(/^#\/?/, "");
1408        const note = window.document.getElementById(id);
1409        if (note) {
1410          return note.innerHTML;
1411        } else {
1412          return "";
1413        }
1414      });
1415    }
1416    const xrefs = window.document.querySelectorAll('a.quarto-xref');
1417    const processXRef = (id, note) => {
1418      // Strip column container classes
1419      const stripColumnClz = (el) => {
1420        el.classList.remove("page-full", "page-columns");
1421        if (el.children) {
1422          for (const child of el.children) {
1423            stripColumnClz(child);
1424          }
1425        }
1426      }
1427      stripColumnClz(note)
1428      if (id === null || id.startsWith('sec-')) {
1429        // Special case sections, only their first couple elements
1430        const container = document.createElement("div");
1431        if (note.children && note.children.length > 2) {
1432          container.appendChild(note.children[0].cloneNode(true));
1433          for (let i = 1; i < note.children.length; i++) {
1434            const child = note.children[i];
1435            if (child.tagName === "P" && child.innerText === "") {
1436              continue;
1437            } else {
1438              container.appendChild(child.cloneNode(true));
1439              break;
1440            }
1441          }
1442          if (window.Quarto?.typesetMath) {
1443            window.Quarto.typesetMath(container);
1444          }
1445          return container.innerHTML
1446        } else {
1447          if (window.Quarto?.typesetMath) {
1448            window.Quarto.typesetMath(note);
1449          }
1450          return note.innerHTML;
1451        }
1452      } else {
1453        // Remove any anchor links if they are present
1454        const anchorLink = note.querySelector('a.anchorjs-link');
1455        if (anchorLink) {
1456          anchorLink.remove();
1457        }
1458        if (window.Quarto?.typesetMath) {
1459          window.Quarto.typesetMath(note);
1460        }
1461        if (note.classList.contains("callout")) {
1462          return note.outerHTML;
1463        } else {
1464          return note.innerHTML;
1465        }
1466      }
1467    }
1468    for (var i=0; i<xrefs.length; i++) {
1469      const xref = xrefs[i];
1470      tippyHover(xref, undefined, function(instance) {
1471        instance.disable();
1472        let url = xref.getAttribute('href');
1473        let hash = undefined; 
1474        if (url.startsWith('#')) {
1475          hash = url;
1476        } else {
1477          try { hash = new URL(url).hash; } catch {}
1478        }
1479        if (hash) {
1480          const id = hash.replace(/^#\/?/, "");
1481          const note = window.document.getElementById(id);
1482          if (note !== null) {
1483            try {
1484              const html = processXRef(id, note.cloneNode(true));
1485              instance.setContent(html);
1486            } finally {
1487              instance.enable();
1488              instance.show();
1489            }
1490          } else {
1491            // See if we can fetch this
1492            fetch(url.split('#')[0])
1493            .then(res => res.text())
1494            .then(html => {
1495              const parser = new DOMParser();
1496              const htmlDoc = parser.parseFromString(html, "text/html");
1497              const note = htmlDoc.getElementById(id);
1498              if (note !== null) {
1499                const html = processXRef(id, note);
1500                instance.setContent(html);
1501              } 
1502            }).finally(() => {
1503              instance.enable();
1504              instance.show();
1505            });
1506          }
1507        } else {
1508          // See if we can fetch a full url (with no hash to target)
1509          // This is a special case and we should probably do some content thinning / targeting
1510          fetch(url)
1511          .then(res => res.text())
1512          .then(html => {
1513            const parser = new DOMParser();
1514            const htmlDoc = parser.parseFromString(html, "text/html");
1515            const note = htmlDoc.querySelector('main.content');
1516            if (note !== null) {
1517              // This should only happen for chapter cross references
1518              // (since there is no id in the URL)
1519              // remove the first header
1520              if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
1521                note.children[0].remove();
1522              }
1523              const html = processXRef(null, note);
1524              instance.setContent(html);
1525            } 
1526          }).finally(() => {
1527            instance.enable();
1528            instance.show();
1529          });
1530        }
1531      }, function(instance) {
1532      });
1533    }
1534        let selectedAnnoteEl;
1535        const selectorForAnnotation = ( cell, annotation) => {
1536          let cellAttr = 'data-code-cell="' + cell + '"';
1537          let lineAttr = 'data-code-annotation="' +  annotation + '"';
1538          const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
1539          return selector;
1540        }
1541        const selectCodeLines = (annoteEl) => {
1542          const doc = window.document;
1543          const targetCell = annoteEl.getAttribute("data-target-cell");
1544          const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
1545          const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
1546          const lines = annoteSpan.getAttribute("data-code-lines").split(",");
1547          const lineIds = lines.map((line) => {
1548            return targetCell + "-" + line;
1549          })
1550          let top = null;
1551          let height = null;
1552          let parent = null;
1553          if (lineIds.length > 0) {
1554              //compute the position of the single el (top and bottom and make a div)
1555              const el = window.document.getElementById(lineIds[0]);
1556              top = el.offsetTop;
1557              height = el.offsetHeight;
1558              parent = el.parentElement.parentElement;
1559            if (lineIds.length > 1) {
1560              const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
1561              const bottom = lastEl.offsetTop + lastEl.offsetHeight;
1562              height = bottom - top;
1563            }
1564            if (top !== null && height !== null && parent !== null) {
1565              // cook up a div (if necessary) and position it 
1566              let div = window.document.getElementById("code-annotation-line-highlight");
1567              if (div === null) {
1568                div = window.document.createElement("div");
1569                div.setAttribute("id", "code-annotation-line-highlight");
1570                div.style.position = 'absolute';
1571                parent.appendChild(div);
1572              }
1573              div.style.top = top - 2 + "px";
1574              div.style.height = height + 4 + "px";
1575              div.style.left = 0;
1576              let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
1577              if (gutterDiv === null) {
1578                gutterDiv = window.document.createElement("div");
1579                gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
1580                gutterDiv.style.position = 'absolute';
1581                const codeCell = window.document.getElementById(targetCell);
1582                const gutter = codeCell.querySelector('.code-annotation-gutter');
1583                gutter.appendChild(gutterDiv);
1584              }
1585              gutterDiv.style.top = top - 2 + "px";
1586              gutterDiv.style.height = height + 4 + "px";
1587            }
1588            selectedAnnoteEl = annoteEl;
1589          }
1590        };
1591        const unselectCodeLines = () => {
1592          const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
1593          elementsIds.forEach((elId) => {
1594            const div = window.document.getElementById(elId);
1595            if (div) {
1596              div.remove();
1597            }
1598          });
1599          selectedAnnoteEl = undefined;
1600        };
1601          // Handle positioning of the toggle
1602      window.addEventListener(
1603        "resize",
1604        throttle(() => {
1605          elRect = undefined;
1606          if (selectedAnnoteEl) {
1607            selectCodeLines(selectedAnnoteEl);
1608          }
1609        }, 10)
1610      );
1611      function throttle(fn, ms) {
1612      let throttle = false;
1613      let timer;
1614        return (...args) => {
1615          if(!throttle) { // first call gets through
1616              fn.apply(this, args);
1617              throttle = true;
1618          } else { // all the others get throttled
1619              if(timer) clearTimeout(timer); // cancel #2
1620              timer = setTimeout(() => {
1621                fn.apply(this, args);
1622                timer = throttle = false;
1623              }, ms);
1624          }
1625        };
1626      }
1627        const annoteTargets = window.document.querySelectorAll('.code-annotation-anchor');
1628        for (let i=0; i<annoteTargets.length; i++) {
1629          const annoteTarget = annoteTargets[i];
1630          const targetCell = annoteTarget.getAttribute("data-target-cell");
1631          const targetAnnotation = annoteTarget.getAttribute("data-target-annotation");
1632          const contentFn = () => {
1633            const content = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
1634            if (content) {
1635              const tipContent = content.cloneNode(true);
1636              tipContent.classList.add("code-annotation-tip-content");
1637              return tipContent.outerHTML;
1638            }
1639          }
1640          const config = {
1641            allowHTML: true,
1642            content: contentFn,
1643            onShow: (instance) => {
1644              selectCodeLines(instance.reference);
1645              instance.reference.classList.add('code-annotation-active');
1646              window.tippy.hideAll();
1647            },
1648            onHide: (instance) => {
1649              unselectCodeLines();
1650              instance.reference.classList.remove('code-annotation-active');
1651            },
1652            maxWidth: 300,
1653            delay: [50, 0],
1654            duration: [200, 0],
1655            offset: [5, 10],
1656            arrow: true,
1657            appendTo: function(el) {
1658              return el.parentElement.parentElement.parentElement;
1659            },
1660            interactive: true,
1661            interactiveBorder: 10,
1662            theme: 'quarto',
1663            placement: 'right',
1664            popperOptions: {
1665              modifiers: [
1666              {
1667                name: 'flip',
1668                options: {
1669                  flipVariations: false, // true by default
1670                  allowedAutoPlacements: ['right'],
1671                  fallbackPlacements: ['right', 'top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left'],
1672                },
1673              },
1674              {
1675                name: 'preventOverflow',
1676                options: {
1677                  mainAxis: false,
1678                  altAxis: false
1679                }
1680              }
1681              ]        
1682            }      
1683          };
1684          window.tippy(annoteTarget, config); 
1685        }
1686    const findCites = (el) => {
1687      const parentEl = el.parentElement;
1688      if (parentEl) {
1689        const cites = parentEl.dataset.cites;
1690        if (cites) {
1691          return {
1692            el,
1693            cites: cites.split(' ')
1694          };
1695        } else {
1696          return findCites(el.parentElement)
1697        }
1698      } else {
1699        return undefined;
1700      }
1701    };
1702    var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
1703    for (var i=0; i<bibliorefs.length; i++) {
1704      const ref = bibliorefs[i];
1705      const citeInfo = findCites(ref);
1706      if (citeInfo) {
1707        tippyHover(citeInfo.el, function() {
1708          var popup = window.document.createElement('div');
1709          citeInfo.cites.forEach(function(cite) {
1710            var citeDiv = window.document.createElement('div');
1711            citeDiv.classList.add('hanging-indent');
1712            citeDiv.classList.add('csl-entry');
1713            var biblioDiv = window.document.getElementById('ref-' + cite);
1714            if (biblioDiv) {
1715              citeDiv.innerHTML = biblioDiv.innerHTML;
1716            }
1717            popup.appendChild(citeDiv);
1718          });
1719          return popup.innerHTML;
1720        });
1721      }
1722    }
1723  });
1724  </script>
1724
1725</div> <!-- /content -->
1726<footer class="footer">
1727  <div class="nav-footer">
1728    <div class="nav-footer-left">
1729      &nbsp;
1730    </div>   
1731    <div class="nav-footer-center">
1732      &nbsp;
1733    </div>
1734    <div class="nav-footer-right">
1735      <ul class="footer-items list-unstyled">
1736    <li class="nav-item compact">
1737    <a class="nav-link" href="https://github.com/ibis-project">
1738      <i class="bi bi-github" role="img">
1739</i> 
1740    </a>
1741  </li>  
1742    <li class="nav-item compact">
1743    <a class="nav-link" href="https://ibis-project.zulipchat.com">
1744      <i class="bi bi-zulip" role="img">
1745</i> 
1746    </a>
1747  </li>  
1748    <li class="nav-item compact">
1749    <a class="nav-link" href="https://ibis-project.org/posts.xml">
1750      <i class="bi bi-rss" role="img">
1751</i> 
1752    </a>
1753  </li>  
1754</ul>
1755    </div>
1756  </div>
1757</footer>
1758
1759
1760
1761
1762</body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.