Skip to content

Table Expressions

Table expressions form the basis for most Ibis expressions.

Table

Bases: Expr, _FixedTextJupyterMixin

Attributes

columns: list[str] property

The list of columns in this table.

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.columns
['species',
 'island',
 'bill_length_mm',
 'bill_depth_mm',
 'flipper_length_mm',
 'body_mass_g',
 'sex',
 'year']

Functions

__contains__(name)

Return whether name is a column in the table.

Parameters:

Name Type Description Default
name str

Possible column name

required

Returns:

Type Description
bool

Whether name is a column in self

Examples:

>>> t = ibis.table(dict(a="string", b="float"), name="t")
>>> "a" in t
True
>>> "c" in t
False

__getattr__(key)

Return the column name of a table.

Parameters:

Name Type Description Default
key str

Column name

required

Returns:

Type Description
Column

Column expression with name key

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.island
┏━━━━━━━━━━━┓
┃ island    ┃
┡━━━━━━━━━━━┩
│ string    │
├───────────┤
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ …         │
└───────────┘

__getitem__(what)

Select items from a table expression.

This method implements square bracket syntax for table expressions, including various forms of projection and filtering.

Parameters:

Name Type Description Default
what

Selection object. This can be a variety of types including strings, ints, lists.

required

Returns:

Type Description
Table | Column

The return type depends on the input. For a single string or int input a column is returned, otherwise a table is returned.

Examples:

>>> import ibis
>>> import ibis.selectors as s
>>> from ibis import _
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
│ Adelie  │ Torgersen │           39.3 │          20.6 │               190 │ … │
│ Adelie  │ Torgersen │           38.9 │          17.8 │               181 │ … │
│ Adelie  │ Torgersen │           39.2 │          19.6 │               195 │ … │
│ Adelie  │ Torgersen │           34.1 │          18.1 │               193 │ … │
│ Adelie  │ Torgersen │           42.0 │          20.2 │               190 │ … │
│ …       │ …         │              … │             … │                 … │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘

Return a column by name

>>> t["island"]
┏━━━━━━━━━━━┓
┃ island    ┃
┡━━━━━━━━━━━┩
│ string    │
├───────────┤
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ …         │
└───────────┘

Return the second column, starting from index 0

>>> t.columns[1]
'island'
>>> t[1]
┏━━━━━━━━━━━┓
┃ island    ┃
┡━━━━━━━━━━━┩
│ string    │
├───────────┤
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ Torgersen │
│ …         │
└───────────┘

Extract a range of rows

>>> t[:2]
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘
>>> t[:5]
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘
>>> t[2:5]
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘

Select columns

>>> t[["island", "bill_length_mm"]].head()
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ island    ┃ bill_length_mm ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ string    │ float64        │
├───────────┼────────────────┤
│ Torgersen │           39.1 │
│ Torgersen │           39.5 │
│ Torgersen │           40.3 │
│ Torgersen │            nan │
│ Torgersen │           36.7 │
└───────────┴────────────────┘
>>> t["island", "bill_length_mm"].head()
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ island    ┃ bill_length_mm ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ string    │ float64        │
├───────────┼────────────────┤
│ Torgersen │           39.1 │
│ Torgersen │           39.5 │
│ Torgersen │           40.3 │
│ Torgersen │            nan │
│ Torgersen │           36.7 │
└───────────┴────────────────┘
>>> t[_.island, _.bill_length_mm].head()
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ island    ┃ bill_length_mm ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ string    │ float64        │
├───────────┼────────────────┤
│ Torgersen │           39.1 │
│ Torgersen │           39.5 │
│ Torgersen │           40.3 │
│ Torgersen │            nan │
│ Torgersen │           36.7 │
└───────────┴────────────────┘

Filtering

>>> t[t.island.lower() != "torgersen"].head()
┏━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string │ float64        │ float64       │ int64             │ … │
├─────────┼────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Biscoe │           37.8 │          18.3 │               174 │ … │
│ Adelie  │ Biscoe │           37.7 │          18.7 │               180 │ … │
│ Adelie  │ Biscoe │           35.9 │          19.2 │               189 │ … │
│ Adelie  │ Biscoe │           38.2 │          18.1 │               185 │ … │
│ Adelie  │ Biscoe │           38.8 │          17.2 │               180 │ … │
└─────────┴────────┴────────────────┴───────────────┴───────────────────┴───┘

Selectors

>>> t[~s.numeric() | (s.numeric() & ~s.c("year"))].head()
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘
>>> t[s.r["bill_length_mm":"body_mass_g"]].head()
┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃
┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩
│ float64        │ float64       │ int64             │ int64       │
├────────────────┼───────────────┼───────────────────┼─────────────┤
│           39.1 │          18.7 │               181 │        3750 │
│           39.5 │          17.4 │               186 │        3800 │
│           40.3 │          18.0 │               195 │        3250 │
│            nan │           nan │              NULL │        NULL │
│           36.7 │          19.3 │               193 │        3450 │
└────────────────┴───────────────┴───────────────────┴─────────────┘

aggregate(metrics=None, by=None, having=None, **kwargs)

Aggregate a table with a given set of reductions grouping by by.

Parameters:

Name Type Description Default
metrics Sequence[ir.Scalar] | None

Aggregate expressions. These can be any scalar-producing expression, including aggregation functions like sum or literal values like ibis.literal(1).

None
by Sequence[ir.Value] | None

Grouping expressions.

None
having Sequence[ir.BooleanValue] | None

Post-aggregation filters. The shape requirements are the same metrics, but the output type for having is boolean.

Expressions like x is None return bool and will not generate a SQL comparison to NULL

None
kwargs ir.Value

Named aggregate expressions

{}

Returns:

Type Description
Table

An aggregate table expression

Examples:

>>> import ibis
>>> from ibis import _
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"fruit": ["apple", "apple", "banana", "orange"], "price": [0.5, 0.5, 0.25, 0.33]})
>>> t
┏━━━━━━━━┳━━━━━━━━━┓
┃ fruit  ┃ price   ┃
┡━━━━━━━━╇━━━━━━━━━┩
│ string │ float64 │
├────────┼─────────┤
│ apple  │    0.50 │
│ apple  │    0.50 │
│ banana │    0.25 │
│ orange │    0.33 │
└────────┴─────────┘
>>> t.aggregate(by=["fruit"], total_cost=_.price.sum(), avg_cost=_.price.mean(), having=_.price.sum() < 0.5)
┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ fruit  ┃ total_cost ┃ avg_cost ┃
┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━┩
│ string │ float64    │ float64  │
├────────┼────────────┼──────────┤
│ banana │       0.25 │     0.25 │
│ orange │       0.33 │     0.33 │
└────────┴────────────┴──────────┘

alias(alias)

Create a table expression with a specific name alias.

This method is useful for exposing an ibis expression to the underlying backend for use in the Table.sql method.

.alias will create a temporary view

.alias creates a temporary view in the database.

This side effect will be removed in a future version of ibis and is not part of the public API.

Parameters:

Name Type Description Default
alias str

Name of the child expression

required

Returns:

Type Description
Table

An table expression

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> expr = t.alias("pingüinos").sql('SELECT * FROM "pingüinos" LIMIT 5')
>>> expr
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘

as_table()

Promote the expression to a table.

This method is a no-op for table expressions.

Returns:

Type Description
Table

A table expression

Examples:

>>> t = ibis.table(dict(a="int"), name="t")
>>> s = t.as_table()
>>> t is s
True

asof_join(left, right, predicates=(), by=(), tolerance=None, *, lname='', rname='{name}_right')

Perform an "as-of" join between left and right.

Similar to a left join except that the match is done on nearest key rather than equal keys.

Optionally, match keys with by before joining with predicates.

Parameters:

Name Type Description Default
left Table

Table expression

required
right Table

Table expression

required
predicates str | ir.BooleanColumn | Sequence[str | ir.BooleanColumn]

Join expressions

()
by str | ir.Column | Sequence[str | ir.Column]

column to group by before joining

()
tolerance str | ir.IntervalScalar | None

Amount of time to look behind when joining

None
lname str

A format string to use to rename overlapping columns in the left table (e.g. "left_{name}").

''
rname str

A format string to use to rename overlapping columns in the right table (e.g. "right_{name}").

'{name}_right'

Returns:

Type Description
Table

Table expression

cache()

Cache the provided expression.

All subsequent operations on the returned expression will be performed on the cached data. Use the with statement to limit the lifetime of a cached table.

This method is idempotent: calling it multiple times in succession will return the same value as the first call.

This method eagerly evaluates the expression prior to caching

Subsequent evaluations will not recompute the expression so method chaining will not incur the overhead of caching more than once.

Returns:

Type Description
Table

Cached table

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> cached_penguins = t.mutate(computation="Heavy Computation").cache()
>>> cached_penguins
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
│ Adelie  │ Torgersen │           39.3 │          20.6 │               190 │ … │
│ Adelie  │ Torgersen │           38.9 │          17.8 │               181 │ … │
│ Adelie  │ Torgersen │           39.2 │          19.6 │               195 │ … │
│ Adelie  │ Torgersen │           34.1 │          18.1 │               193 │ … │
│ Adelie  │ Torgersen │           42.0 │          20.2 │               190 │ … │
│ …       │ …         │              … │             … │                 … │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘

Explicit cache cleanup

>>> with t.mutate(computation="Heavy Computation").cache() as cached_penguins:
...     cached_penguins
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
│ Adelie  │ Torgersen │           39.3 │          20.6 │               190 │ … │
│ Adelie  │ Torgersen │           38.9 │          17.8 │               181 │ … │
│ Adelie  │ Torgersen │           39.2 │          19.6 │               195 │ … │
│ Adelie  │ Torgersen │           34.1 │          18.1 │               193 │ … │
│ Adelie  │ Torgersen │           42.0 │          20.2 │               190 │ … │
│ …       │ …         │              … │             … │                 … │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘

cast(schema)

Cast the columns of a table.

If you need to cast columns to a single type, use selectors.

Parameters:

Name Type Description Default
schema SupportsSchema

Mapping, schema or iterable of pairs to use for casting

required

Returns:

Type Description
Table

Casted table

Examples:

>>> import ibis
>>> import ibis.selectors as s
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.schema()
ibis.Schema {
  species            string
  island             string
  bill_length_mm     float64
  bill_depth_mm      float64
  flipper_length_mm  int64
  body_mass_g        int64
  sex                string
  year               int64
}
>>> cols = ["body_mass_g", "bill_length_mm"]
>>> t[cols].head()
┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ body_mass_g ┃ bill_length_mm ┃
┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ int64       │ float64        │
├─────────────┼────────────────┤
│        3750 │           39.1 │
│        3800 │           39.5 │
│        3250 │           40.3 │
│        NULL │            nan │
│        3450 │           36.7 │
└─────────────┴────────────────┘

Columns not present in the input schema will be passed through unchanged

>>> t.columns
['species', 'island', 'bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g', 'sex', 'year']
>>> expr = t.cast({"body_mass_g": "float64", "bill_length_mm": "int"})
>>> expr.select(*cols).head()
┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ body_mass_g ┃ bill_length_mm ┃
┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ float64     │ int64          │
├─────────────┼────────────────┤
│      3750.0 │             39 │
│      3800.0 │             40 │
│      3250.0 │             40 │
│         nan │           NULL │
│      3450.0 │             37 │
└─────────────┴────────────────┘

Columns that are in the input schema but not in the table raise an error

>>> t.cast({"foo": "string"})
Traceback (most recent call last):
    ...
ibis.common.exceptions.IbisError: Cast schema has fields that are not in the table: ['foo']

count(where=None)

Compute the number of rows in the table.

Parameters:

Name Type Description Default
where ir.BooleanValue | None

Optional boolean expression to filter rows when counting.

None

Returns:

Type Description
IntegerScalar

Number of rows in the table

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"a": ["foo", "bar", "baz"]})
>>> t
┏━━━━━━━━┓
┃ a      ┃
┡━━━━━━━━┩
│ string │
├────────┤
│ foo    │
│ bar    │
│ baz    │
└────────┘
>>> t.count()
3
>>> t.count(t.a != "foo")
2
>>> type(t.count())
<class 'ibis.expr.types.numeric.IntegerScalar'>

cross_join(left, right, *rest, lname='', rname='{name}_right')

Compute the cross join of a sequence of tables.

Parameters:

Name Type Description Default
left Table

Left table

required
right Table

Right table

required
rest Table

Additional tables to cross join

()
lname str

A format string to use to rename overlapping columns in the left table (e.g. "left_{name}").

''
rname str

A format string to use to rename overlapping columns in the right table (e.g. "right_{name}").

'{name}_right'

Returns:

Type Description
Table

Cross join of left, right and rest

Examples:

>>> import ibis
>>> import ibis.selectors as s
>>> from ibis import _
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.count()
344
>>> agg = t.drop("year").agg(s.across(s.numeric(), _.mean()))
>>> expr = t.cross_join(agg)
>>> expr
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
│ Adelie  │ Torgersen │           39.3 │          20.6 │               190 │ … │
│ Adelie  │ Torgersen │           38.9 │          17.8 │               181 │ … │
│ Adelie  │ Torgersen │           39.2 │          19.6 │               195 │ … │
│ Adelie  │ Torgersen │           34.1 │          18.1 │               193 │ … │
│ Adelie  │ Torgersen │           42.0 │          20.2 │               190 │ … │
│ …       │ …         │              … │             … │                 … │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘
>>> expr.columns
['species',
 'island',
 'bill_length_mm',
 'bill_depth_mm',
 'flipper_length_mm',
 'body_mass_g',
 'sex',
 'year',
 'bill_length_mm_right',
 'bill_depth_mm_right',
 'flipper_length_mm_right',
 'body_mass_g_right']
>>> expr.count()
344

difference(*tables, distinct=True)

Compute the set difference of multiple table expressions.

The input tables must have identical schemas.

Parameters:

Name Type Description Default
tables Table

One or more table expressions

()
distinct bool

Only diff distinct rows not occurring in the calling table

True
See Also

ibis.difference

Returns:

Type Description
Table

The rows present in self that are not present in tables.

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t1 = ibis.memtable({"a": [1, 2]})
>>> t1
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     2 │
└───────┘
>>> t2 = ibis.memtable({"a": [2, 3]})
>>> t2
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     2 │
│     3 │
└───────┘
>>> t1.difference(t2)
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
└───────┘

Passing no arguments to difference returns the table expression

This can be useful when you have a sequence of tables to process, and you don't know the length prior to running your program (for example, user input).

>>> t1
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     2 │
└───────┘
>>> t1.difference()
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     2 │
└───────┘
>>> t1.difference().equals(t1)
True

distinct(*, on=None, keep='first')

Return a Table with duplicate rows removed.

Similar to pandas.DataFrame.drop_duplicates().

Some backends do not support keep='last'

Parameters:

Name Type Description Default
on str | Iterable[str] | s.Selector | None

Only consider certain columns for identifying duplicates. By default deduplicate all of the columns.

None
keep Literal['first', 'last'] | None

Determines which duplicates to keep.

  • "first": Drop duplicates except for the first occurrence.
  • "last": Drop duplicates except for the last occurrence.
  • None: Drop all duplicates
'first'

Examples:

>>> import ibis
>>> import ibis.examples as ex
>>> import ibis.selectors as s
>>> ibis.options.interactive = True
>>> t = ex.penguins.fetch()
>>> t
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
│ Adelie  │ Torgersen │           39.3 │          20.6 │               190 │ … │
│ Adelie  │ Torgersen │           38.9 │          17.8 │               181 │ … │
│ Adelie  │ Torgersen │           39.2 │          19.6 │               195 │ … │
│ Adelie  │ Torgersen │           34.1 │          18.1 │               193 │ … │
│ Adelie  │ Torgersen │           42.0 │          20.2 │               190 │ … │
│ …       │ …         │              … │             … │                 … │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘

Compute the distinct rows of a subset of columns

>>> t[["species", "island"]].distinct()
┏━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ species   ┃ island    ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━┩
│ string    │ string    │
├───────────┼───────────┤
│ Adelie    │ Torgersen │
│ Adelie    │ Biscoe    │
│ Adelie    │ Dream     │
│ Gentoo    │ Biscoe    │
│ Chinstrap │ Dream     │
└───────────┴───────────┘

Drop all duplicate rows except the first

>>> t.distinct(on=["species", "island"], keep="first")
┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━┓
┃ species   ┃ island    ┃ bill_length_mm ┃ bill_depth_… ┃ flipper_length_mm ┃  ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━┩
│ string    │ string    │ float64        │ float64      │ int64             │  │
├───────────┼───────────┼────────────────┼──────────────┼───────────────────┼──┤
│ Adelie    │ Torgersen │           39.1 │         18.7 │               181 │  │
│ Adelie    │ Biscoe    │           37.8 │         18.3 │               174 │  │
│ Adelie    │ Dream     │           39.5 │         16.7 │               178 │  │
│ Gentoo    │ Biscoe    │           46.1 │         13.2 │               211 │  │
│ Chinstrap │ Dream     │           46.5 │         17.9 │               192 │  │
└───────────┴───────────┴────────────────┴──────────────┴───────────────────┴──┘

Drop all duplicate rows except the last

>>> t.distinct(on=["species", "island"], keep="last")
┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━┓
┃ species   ┃ island    ┃ bill_length_mm ┃ bill_depth_… ┃ flipper_length_mm ┃  ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━┩
│ string    │ string    │ float64        │ float64      │ int64             │  │
├───────────┼───────────┼────────────────┼──────────────┼───────────────────┼──┤
│ Adelie    │ Torgersen │           43.1 │         19.2 │               197 │  │
│ Adelie    │ Biscoe    │           42.7 │         18.3 │               196 │  │
│ Adelie    │ Dream     │           41.5 │         18.5 │               201 │  │
│ Gentoo    │ Biscoe    │           49.9 │         16.1 │               213 │  │
│ Chinstrap │ Dream     │           50.2 │         18.7 │               198 │  │
└───────────┴───────────┴────────────────┴──────────────┴───────────────────┴──┘

Drop all duplicated rows

>>> expr = t.distinct(on=["species", "island", "year", "bill_length_mm"], keep=None)
>>> expr.count()
273
>>> t.count()
344

You can pass selectors to on

>>> t.distinct(on=~s.numeric())
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Biscoe    │           37.8 │          18.3 │               174 │ … │
│ Adelie  │ Biscoe    │           37.7 │          18.7 │               180 │ … │
│ Adelie  │ Dream     │           39.5 │          16.7 │               178 │ … │
│ Adelie  │ Dream     │           37.2 │          18.1 │               178 │ … │
│ Adelie  │ Dream     │           37.5 │          18.9 │               179 │ … │
│ Gentoo  │ Biscoe    │           46.1 │          13.2 │               211 │ … │
│ Gentoo  │ Biscoe    │           50.0 │          16.3 │               230 │ … │
│ …       │ …         │              … │             … │                 … │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘

The only valid values of keep are "first", "last" and `None

>>> t.distinct(on="species", keep="second")
Traceback (most recent call last):
  ...
ibis.common.exceptions.IbisError: Invalid value for keep: 'second' ...

drop(*fields)

Remove fields from a table.

Parameters:

Name Type Description Default
fields str | Selector

Fields to drop. Strings and selectors are accepted.

()

Returns:

Type Description
Table

A table with all columns matching fields removed.

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
│ Adelie  │ Torgersen │           39.3 │          20.6 │               190 │ … │
│ Adelie  │ Torgersen │           38.9 │          17.8 │               181 │ … │
│ Adelie  │ Torgersen │           39.2 │          19.6 │               195 │ … │
│ Adelie  │ Torgersen │           34.1 │          18.1 │               193 │ … │
│ Adelie  │ Torgersen │           42.0 │          20.2 │               190 │ … │
│ …       │ …         │              … │             … │                 … │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘

Drop one or more columns

>>> t.drop("species").head()
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string    │ float64        │ float64       │ int64             │ … │
├───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Torgersen │            nan │           nan │              NULL │ … │
│ Torgersen │           36.7 │          19.3 │               193 │ … │
└───────────┴────────────────┴───────────────┴───────────────────┴───┘
>>> t.drop("species", "bill_length_mm").head()
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━┓
┃ island    ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex    ┃ … ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━┩
│ string    │ float64       │ int64             │ int64       │ string │ … │
├───────────┼───────────────┼───────────────────┼─────────────┼────────┼───┤
│ Torgersen │          18.7 │               181 │        3750 │ male   │ … │
│ Torgersen │          17.4 │               186 │        3800 │ female │ … │
│ Torgersen │          18.0 │               195 │        3250 │ female │ … │
│ Torgersen │           nan │              NULL │        NULL │ NULL   │ … │
│ Torgersen │          19.3 │               193 │        3450 │ female │ … │
└───────────┴───────────────┴───────────────────┴─────────────┴────────┴───┘

Drop with selectors, mix and match

>>> import ibis.selectors as s
>>> t.drop("species", s.startswith("bill_")).head()
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓
┃ island    ┃ flipper_length_mm ┃ body_mass_g ┃ sex    ┃ year  ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩
│ string    │ int64             │ int64       │ string │ int64 │
├───────────┼───────────────────┼─────────────┼────────┼───────┤
│ Torgersen │               181 │        3750 │ male   │  2007 │
│ Torgersen │               186 │        3800 │ female │  2007 │
│ Torgersen │               195 │        3250 │ female │  2007 │
│ Torgersen │              NULL │        NULL │ NULL   │  2007 │
│ Torgersen │               193 │        3450 │ female │  2007 │
└───────────┴───────────────────┴─────────────┴────────┴───────┘

dropna(subset=None, how='any')

Remove rows with null values from the table.

Parameters:

Name Type Description Default
subset Sequence[str] | str | None

Columns names to consider when dropping nulls. By default all columns are considered.

None
how Literal['any', 'all']

Determine whether a row is removed if there is at least one null value in the row ('any'), or if all row values are null ('all').

'any'

Returns:

Type Description
Table

Table expression

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
│ Adelie  │ Torgersen │           39.3 │          20.6 │               190 │ … │
│ Adelie  │ Torgersen │           38.9 │          17.8 │               181 │ … │
│ Adelie  │ Torgersen │           39.2 │          19.6 │               195 │ … │
│ Adelie  │ Torgersen │           34.1 │          18.1 │               193 │ … │
│ Adelie  │ Torgersen │           42.0 │          20.2 │               190 │ … │
│ …       │ …         │              … │             … │                 … │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘
>>> t.count()
344
>>> t.dropna(["bill_length_mm", "body_mass_g"]).count()
342
>>> t.dropna(how="all").count()  # no rows where all columns are null
344

fillna(replacements)

Fill null values in a table expression.

There is potential lack of type stability with the fillna API

For example, different library versions may impact whether a given backend promotes integer replacement values to floats.

Parameters:

Name Type Description Default
replacements ir.Scalar | Mapping[str, ir.Scalar]

Value with which to fill nulls. If replacements is a mapping, the keys are column names that map to their replacement value. If passed as a scalar all columns are filled with that value.

required

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.sex
┏━━━━━━━━┓
┃ sex    ┃
┡━━━━━━━━┩
│ string │
├────────┤
│ male   │
│ female │
│ female │
│ NULL   │
│ female │
│ male   │
│ female │
│ male   │
│ NULL   │
│ NULL   │
│ …      │
└────────┘
>>> t.fillna({"sex": "unrecorded"}).sex
┏━━━━━━━━━━━━┓
┃ sex        ┃
┡━━━━━━━━━━━━┩
│ string     │
├────────────┤
│ male       │
│ female     │
│ female     │
│ unrecorded │
│ female     │
│ male       │
│ female     │
│ male       │
│ unrecorded │
│ unrecorded │
│ …          │
└────────────┘

Returns:

Type Description
Table

Table expression

filter(predicates)

Select rows from table based on predicates.

Parameters:

Name Type Description Default
predicates ir.BooleanValue | Sequence[ir.BooleanValue] | IfAnyAll

Boolean value expressions used to select rows in table.

required

Returns:

Type Description
Table

Filtered table expression

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
│ Adelie  │ Torgersen │           39.3 │          20.6 │               190 │ … │
│ Adelie  │ Torgersen │           38.9 │          17.8 │               181 │ … │
│ Adelie  │ Torgersen │           39.2 │          19.6 │               195 │ … │
│ Adelie  │ Torgersen │           34.1 │          18.1 │               193 │ … │
│ Adelie  │ Torgersen │           42.0 │          20.2 │               190 │ … │
│ …       │ …         │              … │             … │                 … │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘
>>> t.filter([t.species == "Adelie", t.body_mass_g > 3500]).sex.value_counts().dropna("sex")
┏━━━━━━━━┳━━━━━━━━━━━┓
┃ sex    ┃ sex_count ┃
┡━━━━━━━━╇━━━━━━━━━━━┩
│ string │ int64     │
├────────┼───────────┤
│ male   │        68 │
│ female │        22 │
└────────┴───────────┘

group_by(by=None, **key_exprs)

Create a grouped table expression.

Parameters:

Name Type Description Default
by str | ir.Value | Iterable[str] | Iterable[ir.Value] | None

Grouping expressions

None
key_exprs str | ir.Value | Iterable[str] | Iterable[ir.Value]

Named grouping expressions

{}

Returns:

Type Description
GroupedTable

A grouped table expression

Examples:

>>> import ibis
>>> from ibis import _
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"fruit": ["apple", "apple", "banana", "orange"], "price": [0.5, 0.5, 0.25, 0.33]})
>>> t
┏━━━━━━━━┳━━━━━━━━━┓
┃ fruit  ┃ price   ┃
┡━━━━━━━━╇━━━━━━━━━┩
│ string │ float64 │
├────────┼─────────┤
│ apple  │    0.50 │
│ apple  │    0.50 │
│ banana │    0.25 │
│ orange │    0.33 │
└────────┴─────────┘
>>> t.group_by("fruit").agg(total_cost=_.price.sum(), avg_cost=_.price.mean())
┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ fruit  ┃ total_cost ┃ avg_cost ┃
┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━┩
│ string │ float64    │ float64  │
├────────┼────────────┼──────────┤
│ apple  │       1.00 │     0.50 │
│ banana │       0.25 │     0.25 │
│ orange │       0.33 │     0.33 │
└────────┴────────────┴──────────┘

head(n=5)

Select the first n rows of a table.

The result set is not deterministic without a call to order_by.

Parameters:

Name Type Description Default
n int

Number of rows to include

5

Returns:

Type Description
Table

self limited to n rows

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"a": [1, 1, 2], "b": ["c", "a", "a"]})
>>> t
┏━━━━━━━┳━━━━━━━━┓
┃ a     ┃ b      ┃
┡━━━━━━━╇━━━━━━━━┩
│ int64 │ string │
├───────┼────────┤
│     1 │ c      │
│     1 │ a      │
│     2 │ a      │
└───────┴────────┘
>>> t.head(2)
┏━━━━━━━┳━━━━━━━━┓
┃ a     ┃ b      ┃
┡━━━━━━━╇━━━━━━━━┩
│ int64 │ string │
├───────┼────────┤
│     1 │ c      │
│     1 │ a      │
└───────┴────────┘
See Also

Table.limit Table.order_by

info()

Return summary information about a table.

Returns:

Type Description
Table

Summary of self

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.info()
┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━┓
┃ name              ┃ type    ┃ nullable ┃ nulls ┃ non_nulls ┃ null_frac ┃ … ┃
┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━┩
│ string            │ string  │ boolean  │ int64 │ int64     │ float64   │ … │
├───────────────────┼─────────┼──────────┼───────┼───────────┼───────────┼───┤
│ species           │ string  │ True     │     0 │       344 │  0.000000 │ … │
│ island            │ string  │ True     │     0 │       344 │  0.000000 │ … │
│ bill_length_mm    │ float64 │ True     │     2 │       342 │  0.005814 │ … │
│ bill_depth_mm     │ float64 │ True     │     2 │       342 │  0.005814 │ … │
│ flipper_length_mm │ int64   │ True     │     2 │       342 │  0.005814 │ … │
│ body_mass_g       │ int64   │ True     │     2 │       342 │  0.005814 │ … │
│ sex               │ string  │ True     │    11 │       333 │  0.031977 │ … │
│ year              │ int64   │ True     │     0 │       344 │  0.000000 │ … │
└───────────────────┴─────────┴──────────┴───────┴───────────┴───────────┴───┘

intersect(*tables, distinct=True)

Compute the set intersection of multiple table expressions.

The input tables must have identical schemas.

Parameters:

Name Type Description Default
*tables Table

One or more table expressions

()
distinct bool

Only return distinct rows

True

Returns:

Type Description
Table

A new table containing the intersection of all input tables.

See Also

ibis.intersect

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t1 = ibis.memtable({"a": [1, 2]})
>>> t1
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     2 │
└───────┘
>>> t2 = ibis.memtable({"a": [2, 3]})
>>> t2
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     2 │
│     3 │
└───────┘
>>> t1.intersect(t2)
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     2 │
└───────┘

Passing no arguments to intersect returns the table expression.

This can be useful when you have a sequence of tables to process, and you don't know the length prior to running your program (for example, user input).

>>> t1
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     2 │
└───────┘
>>> t1.intersect()
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     2 │
└───────┘
>>> t1.intersect().equals(t1)
True

join(left, right, predicates=(), how='inner', *, lname='', rname='{name}_right')

Perform a join between two tables.

Parameters:

Name Type Description Default
left Table

Left table to join

required
right Table

Right table to join

required
predicates str | Sequence[str | tuple[str | ir.Column, str | ir.Column] | ir.BooleanColumn]

Boolean or column names to join on

()
how Literal['inner', 'left', 'outer', 'right', 'semi', 'anti', 'any_inner', 'any_left', 'left_semi']

Join method

'inner'
lname str

A format string to use to rename overlapping columns in the left table (e.g. "left_{name}").

''
rname str

A format string to use to rename overlapping columns in the right table (e.g. "right_{name}").

'{name}_right'

Examples:

>>> import ibis
>>> import ibis.selectors as s
>>> import ibis.examples as ex
>>> from ibis import _
>>> ibis.options.interactive = True
>>> movies = ex.ml_latest_small_movies.fetch()
>>> movies
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ movieId ┃ title                            ┃ genres                          ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ int64   │ string                           │ string                          │
├─────────┼──────────────────────────────────┼─────────────────────────────────┤
│       1 │ Toy Story (1995)                 │ Adventure|Animation|Children|C… │
│       2 │ Jumanji (1995)                   │ Adventure|Children|Fantasy      │
│       3 │ Grumpier Old Men (1995)          │ Comedy|Romance                  │
│       4 │ Waiting to Exhale (1995)         │ Comedy|Drama|Romance            │
│       5 │ Father of the Bride Part II (19… │ Comedy                          │
│       6 │ Heat (1995)                      │ Action|Crime|Thriller           │
│       7 │ Sabrina (1995)                   │ Comedy|Romance                  │
│       8 │ Tom and Huck (1995)              │ Adventure|Children              │
│       9 │ Sudden Death (1995)              │ Action                          │
│      10 │ GoldenEye (1995)                 │ Action|Adventure|Thriller       │
│       … │ …                                │ …                               │
└─────────┴──────────────────────────────────┴─────────────────────────────────┘
>>> links = ex.ml_latest_small_links.fetch()
>>> links
┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┓
┃ movieId ┃ imdbId  ┃ tmdbId ┃
┡━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━┩
│ int64   │ string  │ int64  │
├─────────┼─────────┼────────┤
│       1 │ 0114709 │    862 │
│       2 │ 0113497 │   8844 │
│       3 │ 0113228 │  15602 │
│       4 │ 0114885 │  31357 │
│       5 │ 0113041 │  11862 │
│       6 │ 0113277 │    949 │
│       7 │ 0114319 │  11860 │
│       8 │ 0112302 │  45325 │
│       9 │ 0114576 │   9091 │
│      10 │ 0113189 │    710 │
│       … │ …       │      … │
└─────────┴─────────┴────────┘

Implicit inner equality join on the shared movieId column

>>> linked = movies.join(links, "movieId", how="inner")
>>> linked.head()
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┓
┃ movieId ┃ title                  ┃ genres                 ┃ imdbId  ┃ tmdbId ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━┩
│ int64   │ string                 │ string                 │ string  │ int64  │
├─────────┼────────────────────────┼────────────────────────┼─────────┼────────┤
│       1 │ Toy Story (1995)       │ Adventure|Animation|C… │ 0114709 │    862 │
│       2 │ Jumanji (1995)         │ Adventure|Children|Fa… │ 0113497 │   8844 │
│       3 │ Grumpier Old Men (199… │ Comedy|Romance         │ 0113228 │  15602 │
│       4 │ Waiting to Exhale (19… │ Comedy|Drama|Romance   │ 0114885 │  31357 │
│       5 │ Father of the Bride P… │ Comedy                 │ 0113041 │  11862 │
└─────────┴────────────────────────┴────────────────────────┴─────────┴────────┘

Explicit equality join using the default how value of "inner"

>>> linked = movies.join(links, movies.movieId == links.movieId)
>>> linked.head()
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┓
┃ movieId ┃ title                  ┃ genres                 ┃ imdbId  ┃ tmdbId ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━┩
│ int64   │ string                 │ string                 │ string  │ int64  │
├─────────┼────────────────────────┼────────────────────────┼─────────┼────────┤
│       1 │ Toy Story (1995)       │ Adventure|Animation|C… │ 0114709 │    862 │
│       2 │ Jumanji (1995)         │ Adventure|Children|Fa… │ 0113497 │   8844 │
│       3 │ Grumpier Old Men (199… │ Comedy|Romance         │ 0113228 │  15602 │
│       4 │ Waiting to Exhale (19… │ Comedy|Drama|Romance   │ 0114885 │  31357 │
│       5 │ Father of the Bride P… │ Comedy                 │ 0113041 │  11862 │
└─────────┴────────────────────────┴────────────────────────┴─────────┴────────┘

limit(n, offset=0)

Select n rows from self starting at offset.

The result set is not deterministic without a call to order_by.

Parameters:

Name Type Description Default
n int

Number of rows to include

required
offset int

Number of rows to skip first

0

Returns:

Type Description
Table

The first n rows of self starting at offset

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"a": [1, 1, 2], "b": ["c", "a", "a"]})
>>> t
┏━━━━━━━┳━━━━━━━━┓
┃ a     ┃ b      ┃
┡━━━━━━━╇━━━━━━━━┩
│ int64 │ string │
├───────┼────────┤
│     1 │ c      │
│     1 │ a      │
│     2 │ a      │
└───────┴────────┘
>>> t.limit(2)
┏━━━━━━━┳━━━━━━━━┓
┃ a     ┃ b      ┃
┡━━━━━━━╇━━━━━━━━┩
│ int64 │ string │
├───────┼────────┤
│     1 │ c      │
│     1 │ a      │
└───────┴────────┘
See Also

Table.order_by

mutate(exprs=None, **mutations)

Add columns to a table expression.

Parameters:

Name Type Description Default
exprs Sequence[ir.Expr] | None

List of named expressions to add as columns

None
mutations ir.Value

Named expressions using keyword arguments

{}

Returns:

Type Description
Table

Table expression with additional columns

Examples:

>>> import ibis
>>> import ibis.selectors as s
>>> from ibis import _
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch().select("species", "year", "bill_length_mm")
>>> t
┏━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ species ┃ year  ┃ bill_length_mm ┃
┡━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ string  │ int64 │ float64        │
├─────────┼───────┼────────────────┤
│ Adelie  │  2007 │           39.1 │
│ Adelie  │  2007 │           39.5 │
│ Adelie  │  2007 │           40.3 │
│ Adelie  │  2007 │            nan │
│ Adelie  │  2007 │           36.7 │
│ Adelie  │  2007 │           39.3 │
│ Adelie  │  2007 │           38.9 │
│ Adelie  │  2007 │           39.2 │
│ Adelie  │  2007 │           34.1 │
│ Adelie  │  2007 │           42.0 │
│ …       │     … │              … │
└─────────┴───────┴────────────────┘

Add a new column from a per-element expression

>>> t.mutate(next_year=_.year + 1).head()
┏━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ species ┃ year  ┃ bill_length_mm ┃ next_year ┃
┡━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ string  │ int64 │ float64        │ int64     │
├─────────┼───────┼────────────────┼───────────┤
│ Adelie  │  2007 │           39.1 │      2008 │
│ Adelie  │  2007 │           39.5 │      2008 │
│ Adelie  │  2007 │           40.3 │      2008 │
│ Adelie  │  2007 │            nan │      2008 │
│ Adelie  │  2007 │           36.7 │      2008 │
└─────────┴───────┴────────────────┴───────────┘

Add a new column based on an aggregation. Note the automatic broadcasting.

>>> t.select("species", bill_demean=_.bill_length_mm - _.bill_length_mm.mean()).head()
┏━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ species ┃ bill_demean ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━┩
│ string  │ float64     │
├─────────┼─────────────┤
│ Adelie  │    -4.82193 │
│ Adelie  │    -4.42193 │
│ Adelie  │    -3.62193 │
│ Adelie  │         nan │
│ Adelie  │    -7.22193 │
└─────────┴─────────────┘

Mutate across multiple columns

>>> t.mutate(s.across(s.numeric() & ~s.c("year"), _ - _.mean())).head()
┏━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ species ┃ year  ┃ bill_length_mm ┃
┡━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ string  │ int64 │ float64        │
├─────────┼───────┼────────────────┤
│ Adelie  │  2007 │       -4.82193 │
│ Adelie  │  2007 │       -4.42193 │
│ Adelie  │  2007 │       -3.62193 │
│ Adelie  │  2007 │            nan │
│ Adelie  │  2007 │       -7.22193 │
└─────────┴───────┴────────────────┘

order_by(by)

Sort a table by one or more expressions.

Parameters:

Name Type Description Default
by str | ir.Column | tuple[str | ir.Column, bool] | Sequence[str] | Sequence[ir.Column] | Sequence[tuple[str | ir.Column, bool]] | None

Expressions to sort the table by.

required

Returns:

Type Description
Table

Sorted table

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"a": [1, 2, 3], "b": ["c", "b", "a"], "c": [4, 6, 5]})
>>> t
┏━━━━━━━┳━━━━━━━━┳━━━━━━━┓
┃ a     ┃ b      ┃ c     ┃
┡━━━━━━━╇━━━━━━━━╇━━━━━━━┩
│ int64 │ string │ int64 │
├───────┼────────┼───────┤
│     1 │ c      │     4 │
│     2 │ b      │     6 │
│     3 │ a      │     5 │
└───────┴────────┴───────┘
>>> t.order_by("b")
┏━━━━━━━┳━━━━━━━━┳━━━━━━━┓
┃ a     ┃ b      ┃ c     ┃
┡━━━━━━━╇━━━━━━━━╇━━━━━━━┩
│ int64 │ string │ int64 │
├───────┼────────┼───────┤
│     3 │ a      │     5 │
│     2 │ b      │     6 │
│     1 │ c      │     4 │
└───────┴────────┴───────┘
>>> t.order_by(ibis.desc("c"))
┏━━━━━━━┳━━━━━━━━┳━━━━━━━┓
┃ a     ┃ b      ┃ c     ┃
┡━━━━━━━╇━━━━━━━━╇━━━━━━━┩
│ int64 │ string │ int64 │
├───────┼────────┼───────┤
│     2 │ b      │     6 │
│     3 │ a      │     5 │
│     1 │ c      │     4 │
└───────┴────────┴───────┘

pivot_longer(col, *, names_to='name', names_pattern='(.+)', names_transform=None, values_to='value', values_transform=None)

Transform a table from wider to longer.

Parameters:

Name Type Description Default
col str | s.Selector

String column name or selector.

required
names_to str | Iterable[str]

A string or iterable of strings indicating how to name the new pivoted columns.

'name'
names_pattern str | re.Pattern

Pattern to use to extract column names from the input. By default the entire column name is extracted.

'(.+)'
names_transform Callable[[str], ir.Value] | Mapping[str, Callable[[str], ir.Value]] | None

Function or mapping of a name in names_to to a function to transform a column name to a value.

None
values_to str

Name of the pivoted value column.

'value'
values_transform Callable[[ir.Value], ir.Value] | Deferred | None

Apply a function to the value column. This can be a lambda or deferred expression.

None

Returns:

Type Description
Table

Pivoted table

Examples:

Basic usage

>>> import ibis
>>> import ibis.selectors as s
>>> from ibis import _
>>> ibis.options.interactive = True
>>> relig_income = ibis.examples.relig_income_raw.fetch()
>>> relig_income
┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━┓
┃ religion                ┃ <$10k ┃ $10-20k ┃ $20-30k ┃ $30-40k ┃ $40-50k ┃ … ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━┩
│ string                  │ int64 │ int64   │ int64   │ int64   │ int64   │ … │
├─────────────────────────┼───────┼─────────┼─────────┼─────────┼─────────┼───┤
│ Agnostic                │    27 │      34 │      60 │      81 │      76 │ … │
│ Atheist                 │    12 │      27 │      37 │      52 │      35 │ … │
│ Buddhist                │    27 │      21 │      30 │      34 │      33 │ … │
│ Catholic                │   418 │     617 │     732 │     670 │     638 │ … │
│ Don’t know/refused      │    15 │      14 │      15 │      11 │      10 │ … │
│ Evangelical Prot        │   575 │     869 │    1064 │     982 │     881 │ … │
│ Hindu                   │     1 │       9 │       7 │       9 │      11 │ … │
│ Historically Black Prot │   228 │     244 │     236 │     238 │     197 │ … │
│ Jehovah's Witness       │    20 │      27 │      24 │      24 │      21 │ … │
│ Jewish                  │    19 │      19 │      25 │      25 │      30 │ … │
│ …                       │     … │       … │       … │       … │       … │ … │
└─────────────────────────┴───────┴─────────┴─────────┴─────────┴─────────┴───┘

Here we convert column names not matching the selector for the religion column and convert those names into values

>>> relig_income.pivot_longer(~s.c("religion"), names_to="income", values_to="count")
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ religion ┃ income             ┃ count ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ string   │ string             │ int64 │
├──────────┼────────────────────┼───────┤
│ Agnostic │ <$10k              │    27 │
│ Agnostic │ $10-20k            │    34 │
│ Agnostic │ $20-30k            │    60 │
│ Agnostic │ $30-40k            │    81 │
│ Agnostic │ $40-50k            │    76 │
│ Agnostic │ $50-75k            │   137 │
│ Agnostic │ $75-100k           │   122 │
│ Agnostic │ $100-150k          │   109 │
│ Agnostic │ >150k              │    84 │
│ Agnostic │ Don't know/refused │    96 │
│ …        │ …                  │     … │
└──────────┴────────────────────┴───────┘

Simliarly for a different example dataset, we convert names to values but using a different selector and the default values_to value.

>>> world_bank_pop = ibis.examples.world_bank_pop_raw.fetch()
>>> world_bank_pop.head()
┏━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━┓
┃ country ┃ indicator   ┃ 2000         ┃ 2001         ┃ 2002         ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━┩
│ string  │ string      │ float64      │ float64      │ float64      │ … │
├─────────┼─────────────┼──────────────┼──────────────┼──────────────┼───┤
│ ABW     │ SP.URB.TOTL │ 4.244400e+04 │ 4.304800e+04 │ 4.367000e+04 │ … │
│ ABW     │ SP.URB.GROW │ 1.182632e+00 │ 1.413021e+00 │ 1.434560e+00 │ … │
│ ABW     │ SP.POP.TOTL │ 9.085300e+04 │ 9.289800e+04 │ 9.499200e+04 │ … │
│ ABW     │ SP.POP.GROW │ 2.055027e+00 │ 2.225930e+00 │ 2.229056e+00 │ … │
│ AFG     │ SP.URB.TOTL │ 4.436299e+06 │ 4.648055e+06 │ 4.892951e+06 │ … │
└─────────┴─────────────┴──────────────┴──────────────┴──────────────┴───┘
>>> world_bank_pop.pivot_longer(s.matches(r"\d{4}"), names_to="year").head()
┏━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┓
┃ country ┃ indicator   ┃ year   ┃ value   ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━┩
│ string  │ string      │ string │ float64 │
├─────────┼─────────────┼────────┼─────────┤
│ ABW     │ SP.URB.TOTL │ 2000   │ 42444.0 │
│ ABW     │ SP.URB.TOTL │ 2001   │ 43048.0 │
│ ABW     │ SP.URB.TOTL │ 2002   │ 43670.0 │
│ ABW     │ SP.URB.TOTL │ 2003   │ 44246.0 │
│ ABW     │ SP.URB.TOTL │ 2004   │ 44669.0 │
└─────────┴─────────────┴────────┴─────────┘

pivot_longer has some preprocessing capabiltiies like stripping a prefix and applying a function to column names

>>> billboard = ibis.examples.billboard.fetch()
>>> billboard
┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━┓
┃ artist         ┃ track                   ┃ date_entered ┃ wk1   ┃ wk2   ┃ … ┃
┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━┩
│ string         │ string                  │ date         │ int64 │ int64 │ … │
├────────────────┼─────────────────────────┼──────────────┼───────┼───────┼───┤
│ 2 Pac          │ Baby Don't Cry (Keep... │ 2000-02-26   │    87 │    82 │ … │
│ 2Ge+her        │ The Hardest Part Of ... │ 2000-09-02   │    91 │    87 │ … │
│ 3 Doors Down   │ Kryptonite              │ 2000-04-08   │    81 │    70 │ … │
│ 3 Doors Down   │ Loser                   │ 2000-10-21   │    76 │    76 │ … │
│ 504 Boyz       │ Wobble Wobble           │ 2000-04-15   │    57 │    34 │ … │
│ 98^0           │ Give Me Just One Nig... │ 2000-08-19   │    51 │    39 │ … │
│ A*Teens        │ Dancing Queen           │ 2000-07-08   │    97 │    97 │ … │
│ Aaliyah        │ I Don't Wanna           │ 2000-01-29   │    84 │    62 │ … │
│ Aaliyah        │ Try Again               │ 2000-03-18   │    59 │    53 │ … │
│ Adams, Yolanda │ Open My Heart           │ 2000-08-26   │    76 │    76 │ … │
│ …              │ …                       │ …            │     … │     … │ … │
└────────────────┴─────────────────────────┴──────────────┴───────┴───────┴───┘
>>> billboard.pivot_longer(
...     s.startswith("wk"),
...     names_to="week",
...     names_pattern=r"wk(.+)",
...     names_transform=int,
...     values_to="rank",
...     values_transform=_.cast("int"),
... ).dropna("rank")
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━┳━━━━━━━┓
┃ artist  ┃ track                   ┃ date_entered ┃ week ┃ rank  ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━╇━━━━━━━┩
│ string  │ string                  │ date         │ int8 │ int64 │
├─────────┼─────────────────────────┼──────────────┼──────┼───────┤
│ 2 Pac   │ Baby Don't Cry (Keep... │ 2000-02-26   │    1 │    87 │
│ 2 Pac   │ Baby Don't Cry (Keep... │ 2000-02-26   │    2 │    82 │
│ 2 Pac   │ Baby Don't Cry (Keep... │ 2000-02-26   │    3 │    72 │
│ 2 Pac   │ Baby Don't Cry (Keep... │ 2000-02-26   │    4 │    77 │
│ 2 Pac   │ Baby Don't Cry (Keep... │ 2000-02-26   │    5 │    87 │
│ 2 Pac   │ Baby Don't Cry (Keep... │ 2000-02-26   │    6 │    94 │
│ 2 Pac   │ Baby Don't Cry (Keep... │ 2000-02-26   │    7 │    99 │
│ 2Ge+her │ The Hardest Part Of ... │ 2000-09-02   │    1 │    91 │
│ 2Ge+her │ The Hardest Part Of ... │ 2000-09-02   │    2 │    87 │
│ 2Ge+her │ The Hardest Part Of ... │ 2000-09-02   │    3 │    92 │
│ …       │ …                       │ …            │    … │     … │
└─────────┴─────────────────────────┴──────────────┴──────┴───────┘

You can use regular expression capture groups to extract multiple variables stored in column names

>>> who = ibis.examples.who.fetch()
>>> who
┏━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━┓
┃ country     ┃ iso2   ┃ iso3   ┃ year  ┃ new_sp_m014 ┃ new_sp_m1524 ┃ … ┃
┡━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━┩
│ string      │ string │ string │ int64 │ int64       │ int64        │ … │
├─────────────┼────────┼────────┼───────┼─────────────┼──────────────┼───┤
│ Afghanistan │ AF     │ AFG    │  1980 │        NULL │         NULL │ … │
│ Afghanistan │ AF     │ AFG    │  1981 │        NULL │         NULL │ … │
│ Afghanistan │ AF     │ AFG    │  1982 │        NULL │         NULL │ … │
│ Afghanistan │ AF     │ AFG    │  1983 │        NULL │         NULL │ … │
│ Afghanistan │ AF     │ AFG    │  1984 │        NULL │         NULL │ … │
│ Afghanistan │ AF     │ AFG    │  1985 │        NULL │         NULL │ … │
│ Afghanistan │ AF     │ AFG    │  1986 │        NULL │         NULL │ … │
│ Afghanistan │ AF     │ AFG    │  1987 │        NULL │         NULL │ … │
│ Afghanistan │ AF     │ AFG    │  1988 │        NULL │         NULL │ … │
│ Afghanistan │ AF     │ AFG    │  1989 │        NULL │         NULL │ … │
│ …           │ …      │ …      │     … │           … │            … │ … │
└─────────────┴────────┴────────┴───────┴─────────────┴──────────────┴───┘
>>> len(who.columns)
60
>>> who.pivot_longer(
...     s.r["new_sp_m014":"newrel_f65"],
...     names_to=["diagnosis", "gender", "age"],
...     names_pattern="new_?(.*)_(.)(.*)",
...     values_to="count",
... )
┏━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━┳━━━━━━━┓
┃ country     ┃ iso2   ┃ iso3   ┃ year  ┃ diagnosis ┃ gender ┃ age    ┃ count ┃
┡━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━╇━━━━━━━┩
│ string      │ string │ string │ int64 │ string    │ string │ string │ int64 │
├─────────────┼────────┼────────┼───────┼───────────┼────────┼────────┼───────┤
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │ m      │ 014    │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │ m      │ 1524   │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │ m      │ 2534   │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │ m      │ 3544   │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │ m      │ 4554   │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │ m      │ 5564   │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │ m      │ 65     │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │ f      │ 014    │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │ f      │ 1524   │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │ f      │ 2534   │  NULL │
│ …           │ …      │ …      │     … │ …         │ …      │ …      │     … │
└─────────────┴────────┴────────┴───────┴───────────┴────────┴────────┴───────┘

names_transform is flexible, and can be:

1. A mapping of one or more names in `names_to` to callable
2. A callable that will be applied to every name

Let's recode gender and age to numeric values using a mapping

>>> who.pivot_longer(
...     s.r["new_sp_m014":"newrel_f65"],
...     names_to=["diagnosis", "gender", "age"],
...     names_pattern="new_?(.*)_(.)(.*)",
...     names_transform=dict(
...         gender={"m": 1, "f": 2}.get,
...         age=dict(zip(["014", "1524", "2534", "3544", "4554", "5564", "65"], range(7))).get,
...     ),
...     values_to="count",
... )
┏━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━┳━━━━━━━┓
┃ country     ┃ iso2   ┃ iso3   ┃ year  ┃ diagnosis ┃ gender ┃ age  ┃ count ┃
┡━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━╇━━━━━━╇━━━━━━━┩
│ string      │ string │ string │ int64 │ string    │ int8   │ int8 │ int64 │
├─────────────┼────────┼────────┼───────┼───────────┼────────┼──────┼───────┤
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │      1 │    0 │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │      1 │    1 │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │      1 │    2 │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │      1 │    3 │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │      1 │    4 │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │      1 │    5 │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │      1 │    6 │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │      2 │    0 │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │      2 │    1 │  NULL │
│ Afghanistan │ AF     │ AFG    │  1980 │ sp        │      2 │    2 │  NULL │
│ …           │ …      │ …      │     … │ …         │      … │    … │     … │
└─────────────┴────────┴────────┴───────┴───────────┴────────┴──────┴───────┘

The number of match groups in names_pattern must match the length of names_to

>>> who.pivot_longer(
...     s.r["new_sp_m014":"newrel_f65"],
...     names_to=["diagnosis", "gender", "age"],
...     names_pattern="new_?(.*)_.(.*)",
... )
Traceback (most recent call last):
  ...
ibis.common.exceptions.IbisInputError: Number of match groups in `names_pattern` ...

names_transform must be a mapping or callable

>>> who.pivot_longer(s.r["new_sp_m014":"newrel_f65"], names_transform="upper")
Traceback (most recent call last):
  ...
ibis.common.exceptions.IbisTypeError: ... Got <class 'str'>

pivot_wider(*, id_cols=None, names_from='name', names_prefix='', names_sep='_', names_sort=False, names=None, values_from='value', values_fill=None, values_agg='arbitrary')

Pivot a table to a wider format.

Parameters:

Name Type Description Default
id_cols s.Selector | None

A set of columns that uniquely identify each observation.

None
names_from str | Iterable[str] | s.Selector

An argument describing which column or columns to use to get the name of the output columns.

'name'
names_prefix str

String added to the start of every column name.

''
names_sep str

If names_from or values_from contains multiple columns, this argument will be used to join their values together into a single string to use as a column name.

'_'
names_sort bool

If True columns are sorted. If False column names are ordered by appearance.

False
names Iterable[str] | None

An explicit sequence of values to look for in columns matching names_from.

  • When this value is None, the values will be computed from names_from.
  • When this value is not None, each element's length must match the length of names_from.

See examples below for more detail.

None
values_from str | Iterable[str] | s.Selector

An argument describing which column or columns to get the cell values from.

'value'
values_fill int | float | str | ir.Scalar | None

A scalar value that specifies what each value should be filled with when missing.

None
values_agg str | Callable[[ir.Value], ir.Scalar] | Deferred

A function applied to the value in each cell in the output.

'arbitrary'

Returns:

Type Description
Table

Wider pivoted table

Examples:

>>> import ibis
>>> import ibis.selectors as s
>>> from ibis import _
>>> ibis.options.interactive = True

Basic usage

>>> fish_encounters = ibis.examples.fish_encounters.fetch()
>>> fish_encounters
┏━━━━━━━┳━━━━━━━━━┳━━━━━━━┓
┃ fish  ┃ station ┃ seen  ┃
┡━━━━━━━╇━━━━━━━━━╇━━━━━━━┩
│ int64 │ string  │ int64 │
├───────┼─────────┼───────┤
│  4842 │ Release │     1 │
│  4842 │ I80_1   │     1 │
│  4842 │ Lisbon  │     1 │
│  4842 │ Rstr    │     1 │
│  4842 │ Base_TD │     1 │
│  4842 │ BCE     │     1 │
│  4842 │ BCW     │     1 │
│  4842 │ BCE2    │     1 │
│  4842 │ BCW2    │     1 │
│  4842 │ MAE     │     1 │
│     … │ …       │     … │
└───────┴─────────┴───────┘
>>> fish_encounters.pivot_wider(names_from="station", values_from="seen")
┏━━━━━━━┳━━━━━━━━━┳━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━┓
┃ fish  ┃ Release ┃ I80_1 ┃ Lisbon ┃ Rstr  ┃ Base_TD ┃ BCE   ┃ BCW   ┃ … ┃
┡━━━━━━━╇━━━━━━━━━╇━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━┩
│ int64 │ int64   │ int64 │ int64  │ int64 │ int64   │ int64 │ int64 │ … │
├───────┼─────────┼───────┼────────┼───────┼─────────┼───────┼───────┼───┤
│  4842 │       1 │     1 │      1 │     1 │       1 │     1 │     1 │ … │
│  4843 │       1 │     1 │      1 │     1 │       1 │     1 │     1 │ … │
│  4844 │       1 │     1 │      1 │     1 │       1 │     1 │     1 │ … │
│  4845 │       1 │     1 │      1 │     1 │       1 │  NULL │  NULL │ … │
│  4847 │       1 │     1 │      1 │  NULL │    NULL │  NULL │  NULL │ … │
│  4848 │       1 │     1 │      1 │     1 │    NULL │  NULL │  NULL │ … │
│  4849 │       1 │     1 │   NULL │  NULL │    NULL │  NULL │  NULL │ … │
│  4850 │       1 │     1 │   NULL │     1 │       1 │     1 │     1 │ … │
│  4851 │       1 │     1 │   NULL │  NULL │    NULL │  NULL │  NULL │ … │
│  4854 │       1 │     1 │   NULL │  NULL │    NULL │  NULL │  NULL │ … │
│     … │       … │     … │      … │     … │       … │     … │     … │ … │
└───────┴─────────┴───────┴────────┴───────┴─────────┴───────┴───────┴───┘

Fill missing pivoted values using values_fill

>>> fish_encounters.pivot_wider(names_from="station", values_from="seen", values_fill=0)
┏━━━━━━━┳━━━━━━━━━┳━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━┓
┃ fish  ┃ Release ┃ I80_1 ┃ Lisbon ┃ Rstr  ┃ Base_TD ┃ BCE   ┃ BCW   ┃ … ┃
┡━━━━━━━╇━━━━━━━━━╇━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━┩
│ int64 │ int64   │ int64 │ int64  │ int64 │ int64   │ int64 │ int64 │ … │
├───────┼─────────┼───────┼────────┼───────┼─────────┼───────┼───────┼───┤
│  4842 │       1 │     1 │      1 │     1 │       1 │     1 │     1 │ … │
│  4843 │       1 │     1 │      1 │     1 │       1 │     1 │     1 │ … │
│  4844 │       1 │     1 │      1 │     1 │       1 │     1 │     1 │ … │
│  4845 │       1 │     1 │      1 │     1 │       1 │     0 │     0 │ … │
│  4847 │       1 │     1 │      1 │     0 │       0 │     0 │     0 │ … │
│  4848 │       1 │     1 │      1 │     1 │       0 │     0 │     0 │ … │
│  4849 │       1 │     1 │      0 │     0 │       0 │     0 │     0 │ … │
│  4850 │       1 │     1 │      0 │     1 │       1 │     1 │     1 │ … │
│  4851 │       1 │     1 │      0 │     0 │       0 │     0 │     0 │ … │
│  4854 │       1 │     1 │      0 │     0 │       0 │     0 │     0 │ … │
│     … │       … │     … │      … │     … │       … │     … │     … │ … │
└───────┴─────────┴───────┴────────┴───────┴─────────┴───────┴───────┴───┘

Compute multiple values columns

>>> us_rent_income = ibis.examples.us_rent_income.fetch()
>>> us_rent_income
┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┓
┃ geoid  ┃ name       ┃ variable ┃ estimate ┃ moe   ┃
┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━┩
│ string │ string     │ string   │ int64    │ int64 │
├────────┼────────────┼──────────┼──────────┼───────┤
│ 01     │ Alabama    │ income   │    24476 │   136 │
│ 01     │ Alabama    │ rent     │      747 │     3 │
│ 02     │ Alaska     │ income   │    32940 │   508 │
│ 02     │ Alaska     │ rent     │     1200 │    13 │
│ 04     │ Arizona    │ income   │    27517 │   148 │
│ 04     │ Arizona    │ rent     │      972 │     4 │
│ 05     │ Arkansas   │ income   │    23789 │   165 │
│ 05     │ Arkansas   │ rent     │      709 │     5 │
│ 06     │ California │ income   │    29454 │   109 │
│ 06     │ California │ rent     │     1358 │     3 │
│ …      │ …          │ …        │        … │     … │
└────────┴────────────┴──────────┴──────────┴───────┘
>>> us_rent_income.pivot_wider(names_from="variable", values_from=["estimate", "moe"])
┏━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━┓
┃ geoid  ┃ name                 ┃ estimate_income ┃ moe_income ┃ … ┃
┡━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━┩
│ string │ string               │ int64           │ int64      │ … │
├────────┼──────────────────────┼─────────────────┼────────────┼───┤
│ 01     │ Alabama              │           24476 │        136 │ … │
│ 02     │ Alaska               │           32940 │        508 │ … │
│ 04     │ Arizona              │           27517 │        148 │ … │
│ 05     │ Arkansas             │           23789 │        165 │ … │
│ 06     │ California           │           29454 │        109 │ … │
│ 08     │ Colorado             │           32401 │        109 │ … │
│ 09     │ Connecticut          │           35326 │        195 │ … │
│ 10     │ Delaware             │           31560 │        247 │ … │
│ 11     │ District of Columbia │           43198 │        681 │ … │
│ 12     │ Florida              │           25952 │         70 │ … │
│ …      │ …                    │               … │          … │ … │
└────────┴──────────────────────┴─────────────────┴────────────┴───┘

The column name separator can be changed using the names_sep parameter

>>> us_rent_income.pivot_wider(
...     names_from="variable",
...     names_sep=".",
...     values_from=s.c("estimate", "moe"),
... )
┏━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━┓
┃ geoid  ┃ name                 ┃ estimate.income ┃ moe.income ┃ … ┃
┡━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━┩
│ string │ string               │ int64           │ int64      │ … │
├────────┼──────────────────────┼─────────────────┼────────────┼───┤
│ 01     │ Alabama              │           24476 │        136 │ … │
│ 02     │ Alaska               │           32940 │        508 │ … │
│ 04     │ Arizona              │           27517 │        148 │ … │
│ 05     │ Arkansas             │           23789 │        165 │ … │
│ 06     │ California           │           29454 │        109 │ … │
│ 08     │ Colorado             │           32401 │        109 │ … │
│ 09     │ Connecticut          │           35326 │        195 │ … │
│ 10     │ Delaware             │           31560 │        247 │ … │
│ 11     │ District of Columbia │           43198 │        681 │ … │
│ 12     │ Florida              │           25952 │         70 │ … │
│ …      │ …                    │               … │          … │ … │
└────────┴──────────────────────┴─────────────────┴────────────┴───┘

Supply an alternative function to summarize values

>>> warpbreaks = ibis.examples.warpbreaks.fetch().select("wool", "tension", "breaks")
>>> warpbreaks
┏━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┓
┃ wool   ┃ tension ┃ breaks ┃
┡━━━━━━━━╇━━━━━━━━━╇━━━━━━━━┩
│ string │ string  │ int64  │
├────────┼─────────┼────────┤
│ A      │ L       │     26 │
│ A      │ L       │     30 │
│ A      │ L       │     54 │
│ A      │ L       │     25 │
│ A      │ L       │     70 │
│ A      │ L       │     52 │
│ A      │ L       │     51 │
│ A      │ L       │     26 │
│ A      │ L       │     67 │
│ A      │ M       │     18 │
│ …      │ …       │      … │
└────────┴─────────┴────────┘
>>> warpbreaks.pivot_wider(names_from="wool", values_from="breaks", values_agg="mean")
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ tension ┃ A         ┃ B         ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━┩
│ string  │ float64   │ float64   │
├─────────┼───────────┼───────────┤
│ L       │ 44.555556 │ 28.222222 │
│ M       │ 24.000000 │ 28.777778 │
│ H       │ 24.555556 │ 18.777778 │
└─────────┴───────────┴───────────┘

Passing Deferred objects to values_agg is supported

>>> warpbreaks.pivot_wider(
...     names_from="tension",
...     values_from="breaks",
...     values_agg=_.sum(),
... )
┏━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┓
┃ wool   ┃ L     ┃ M     ┃ H     ┃
┡━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━┩
│ string │ int64 │ int64 │ int64 │
├────────┼───────┼───────┼───────┤
│ A      │   401 │   216 │   221 │
│ B      │   254 │   259 │   169 │
└────────┴───────┴───────┴───────┘

Use a custom aggregate function

>>> warpbreaks.pivot_wider(
...     names_from="wool",
...     values_from="breaks",
...     values_agg=lambda col: col.std() / col.mean(),
... )
┏━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┓
┃ tension ┃ A        ┃ B        ┃
┡━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━┩
│ string  │ float64  │ float64  │
├─────────┼──────────┼──────────┤
│ L       │ 0.406183 │ 0.349325 │
│ M       │ 0.360844 │ 0.327719 │
│ H       │ 0.418344 │ 0.260590 │
└─────────┴──────────┴──────────┘

Generate some random data, setting the random seed for reproducibility

>>> import random
>>> random.seed(0)
>>> raw = ibis.memtable(
...     [
...         dict(
...             product=product,
...             country=country,
...             year=year,
...             production=random.random(),
...         )
...         for product in "AB"
...         for country in ["AI", "EI"]
...         for year in range(2000, 2015)
...     ]
... )
>>> production = raw.filter(
...     ((_.product == "A") & (_.country == "AI")) | (_.product == "B")
... )
>>> production
┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━┓
┃ product ┃ country ┃ year  ┃ production ┃
┡━━━━━━━━━╇━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━┩
│ string  │ string  │ int64 │ float64    │
├─────────┼─────────┼───────┼────────────┤
│ B       │ AI      │  2000 │   0.477010 │
│ B       │ AI      │  2001 │   0.865310 │
│ B       │ AI      │  2002 │   0.260492 │
│ B       │ AI      │  2003 │   0.805028 │
│ B       │ AI      │  2004 │   0.548699 │
│ B       │ AI      │  2005 │   0.014042 │
│ B       │ AI      │  2006 │   0.719705 │
│ B       │ AI      │  2007 │   0.398824 │
│ B       │ AI      │  2008 │   0.824845 │
│ B       │ AI      │  2009 │   0.668153 │
│ …       │ …       │     … │          … │
└─────────┴─────────┴───────┴────────────┘

Pivoting with multiple name columns

>>> production.pivot_wider(
...     names_from=["product", "country"],
...     values_from="production",
... )
┏━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┓
┃ year  ┃ B_AI     ┃ B_EI     ┃ A_AI     ┃
┡━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━┩
│ int64 │ float64  │ float64  │ float64  │
├───────┼──────────┼──────────┼──────────┤
│  2000 │ 0.477010 │ 0.870471 │ 0.844422 │
│  2001 │ 0.865310 │ 0.191067 │ 0.757954 │
│  2002 │ 0.260492 │ 0.567511 │ 0.420572 │
│  2003 │ 0.805028 │ 0.238616 │ 0.258917 │
│  2004 │ 0.548699 │ 0.967540 │ 0.511275 │
│  2005 │ 0.014042 │ 0.803179 │ 0.404934 │
│  2006 │ 0.719705 │ 0.447970 │ 0.783799 │
│  2007 │ 0.398824 │ 0.080446 │ 0.303313 │
│  2008 │ 0.824845 │ 0.320055 │ 0.476597 │
│  2009 │ 0.668153 │ 0.507941 │ 0.583382 │
│     … │        … │        … │        … │
└───────┴──────────┴──────────┴──────────┘

Select a subset of names. This call incurs no computation when constructing the expression.

>>> production.pivot_wider(
...     names_from=["product", "country"],
...     names=[("A", "AI"), ("B", "AI")],
...     values_from="production",
... )
┏━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┓
┃ year  ┃ A_AI     ┃ B_AI     ┃
┡━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━┩
│ int64 │ float64  │ float64  │
├───────┼──────────┼──────────┤
│  2000 │ 0.844422 │ 0.477010 │
│  2001 │ 0.757954 │ 0.865310 │
│  2002 │ 0.420572 │ 0.260492 │
│  2003 │ 0.258917 │ 0.805028 │
│  2004 │ 0.511275 │ 0.548699 │
│  2005 │ 0.404934 │ 0.014042 │
│  2006 │ 0.783799 │ 0.719705 │
│  2007 │ 0.303313 │ 0.398824 │
│  2008 │ 0.476597 │ 0.824845 │
│  2009 │ 0.583382 │ 0.668153 │
│     … │        … │        … │
└───────┴──────────┴──────────┘

Sort the new columns' names

>>> production.pivot_wider(
...     names_from=["product", "country"],
...     values_from="production",
...     names_sort=True,
... )
┏━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┓
┃ year  ┃ A_AI     ┃ B_AI     ┃ B_EI     ┃
┡━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━┩
│ int64 │ float64  │ float64  │ float64  │
├───────┼──────────┼──────────┼──────────┤
│  2000 │ 0.844422 │ 0.477010 │ 0.870471 │
│  2001 │ 0.757954 │ 0.865310 │ 0.191067 │
│  2002 │ 0.420572 │ 0.260492 │ 0.567511 │
│  2003 │ 0.258917 │ 0.805028 │ 0.238616 │
│  2004 │ 0.511275 │ 0.548699 │ 0.967540 │
│  2005 │ 0.404934 │ 0.014042 │ 0.803179 │
│  2006 │ 0.783799 │ 0.719705 │ 0.447970 │
│  2007 │ 0.303313 │ 0.398824 │ 0.080446 │
│  2008 │ 0.476597 │ 0.824845 │ 0.320055 │
│  2009 │ 0.583382 │ 0.668153 │ 0.507941 │
│     … │        … │        … │        … │
└───────┴──────────┴──────────┴──────────┘

relabel(substitutions)

Rename columns in the table.

Parameters:

Name Type Description Default
substitutions Mapping[str, str] | Callable[[str], str | None] | str | Literal['snake_case']

A mapping, function, or format string mapping old to new column names. If a column isn't in the mapping (or if the callable returns None) it is left with its original name. May also pass a format string to rename all columns, like "prefix_{name}". Also accepts the literal string "snake_case", which will relabel all columns to use a snake_case naming convention.

required

Returns:

Type Description
Table

A relabeled table expressi

Examples:

>>> import ibis
>>> import ibis.selectors as s
>>> ibis.options.interactive = True
>>> first3 = s.r[:3]  # first 3 columns
>>> t = ibis.examples.penguins_raw_raw.fetch().select(first3)
>>> t
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ studyName ┃ Sample Number ┃ Species                             ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ string    │ int64         │ string                              │
├───────────┼───────────────┼─────────────────────────────────────┤
│ PAL0708   │             1 │ Adelie Penguin (Pygoscelis adeliae) │
│ PAL0708   │             2 │ Adelie Penguin (Pygoscelis adeliae) │
│ PAL0708   │             3 │ Adelie Penguin (Pygoscelis adeliae) │
│ PAL0708   │             4 │ Adelie Penguin (Pygoscelis adeliae) │
│ PAL0708   │             5 │ Adelie Penguin (Pygoscelis adeliae) │
│ PAL0708   │             6 │ Adelie Penguin (Pygoscelis adeliae) │
│ PAL0708   │             7 │ Adelie Penguin (Pygoscelis adeliae) │
│ PAL0708   │             8 │ Adelie Penguin (Pygoscelis adeliae) │
│ PAL0708   │             9 │ Adelie Penguin (Pygoscelis adeliae) │
│ PAL0708   │            10 │ Adelie Penguin (Pygoscelis adeliae) │
│ …         │             … │ …                                   │
└───────────┴───────────────┴─────────────────────────────────────┘

Relabel column names using a mapping from old name to new name

>>> t.relabel({"studyName": "study_name"}).head(1)
┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ study_name ┃ Sample Number ┃ Species                             ┃
┡━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ string     │ int64         │ string                              │
├────────────┼───────────────┼─────────────────────────────────────┤
│ PAL0708    │             1 │ Adelie Penguin (Pygoscelis adeliae) │
└────────────┴───────────────┴─────────────────────────────────────┘

Relabel column names using a snake_case convention

>>> t.relabel("snake_case").head(1)
┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ study_name ┃ sample_number ┃ species                             ┃
┡━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ string     │ int64         │ string                              │
├────────────┼───────────────┼─────────────────────────────────────┤
│ PAL0708    │             1 │ Adelie Penguin (Pygoscelis adeliae) │
└────────────┴───────────────┴─────────────────────────────────────┘

Relabel columns using a format string

>>> t.relabel("p_{name}").head(1)
┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ p_studyName ┃ p_Sample Number ┃ p_Species                           ┃
┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ string      │ int64           │ string                              │
├─────────────┼─────────────────┼─────────────────────────────────────┤
│ PAL0708     │               1 │ Adelie Penguin (Pygoscelis adeliae) │
└─────────────┴─────────────────┴─────────────────────────────────────┘

Relabel column names using a callable

>>> t.relabel(str.upper).head(1)
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ STUDYNAME ┃ SAMPLE NUMBER ┃ SPECIES                             ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ string    │ int64         │ string                              │
├───────────┼───────────────┼─────────────────────────────────────┤
│ PAL0708   │             1 │ Adelie Penguin (Pygoscelis adeliae) │
└───────────┴───────────────┴─────────────────────────────────────┘

rowid()

A unique integer per row.

This operation is only valid on physical tables

Any further meaning behind this expression is backend dependent. Generally this corresponds to some index into the database storage (for example, sqlite or duckdb's rowid).

For a monotonically increasing row number, see ibis.row_number.

Returns:

Type Description
IntegerColumn

An integer column

schema()

Return the schema for this table.

Returns:

Type Description
Schema

The table's schema.

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.schema()
ibis.Schema {
  species            string
  island             string
  bill_length_mm     float64
  bill_depth_mm      float64
  flipper_length_mm  int64
  body_mass_g        int64
  sex                string
  year               int64
}

select(*exprs, **named_exprs)

Compute a new table expression using exprs and named_exprs.

Passing an aggregate function to this method will broadcast the aggregate's value over the number of rows in the table and automatically constructs a window function expression. See the examples section for more details.

For backwards compatibility the keyword argument exprs is reserved and cannot be used to name an expression. This behavior will be removed in v4.

Parameters:

Name Type Description Default
exprs ir.Value | str | Iterable[ir.Value | str]

Column expression, string, or list of column expressions and strings.

()
named_exprs ir.Value | str

Column expressions

{}

Returns:

Type Description
Table

Table expression

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ species ┃ island    ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ … ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━┩
│ string  │ string    │ float64        │ float64       │ int64             │ … │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼───┤
│ Adelie  │ Torgersen │           39.1 │          18.7 │               181 │ … │
│ Adelie  │ Torgersen │           39.5 │          17.4 │               186 │ … │
│ Adelie  │ Torgersen │           40.3 │          18.0 │               195 │ … │
│ Adelie  │ Torgersen │            nan │           nan │              NULL │ … │
│ Adelie  │ Torgersen │           36.7 │          19.3 │               193 │ … │
│ Adelie  │ Torgersen │           39.3 │          20.6 │               190 │ … │
│ Adelie  │ Torgersen │           38.9 │          17.8 │               181 │ … │
│ Adelie  │ Torgersen │           39.2 │          19.6 │               195 │ … │
│ Adelie  │ Torgersen │           34.1 │          18.1 │               193 │ … │
│ Adelie  │ Torgersen │           42.0 │          20.2 │               190 │ … │
│ …       │ …         │              … │             … │                 … │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘

Simple projection

>>> t.select("island", "bill_length_mm").head()
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ island    ┃ bill_length_mm ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ string    │ float64        │
├───────────┼────────────────┤
│ Torgersen │           39.1 │
│ Torgersen │           39.5 │
│ Torgersen │           40.3 │
│ Torgersen │            nan │
│ Torgersen │           36.7 │
└───────────┴────────────────┘

Projection by zero-indexed column position

>>> t.select(0, 4).head()
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ species ┃ flipper_length_mm ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ string  │ int64             │
├─────────┼───────────────────┤
│ Adelie  │               181 │
│ Adelie  │               186 │
│ Adelie  │               195 │
│ Adelie  │              NULL │
│ Adelie  │               193 │
└─────────┴───────────────────┘

Projection with renaming and compute in one call

>>> t.select(next_year=t.year + 1).head()
┏━━━━━━━━━━━┓
┃ next_year ┃
┡━━━━━━━━━━━┩
│ int64     │
├───────────┤
│      2008 │
│      2008 │
│      2008 │
│      2008 │
│      2008 │
└───────────┘

Projection with aggregation expressions

>>> t.select("island", bill_mean=t.bill_length_mm.mean()).head()
┏━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ island    ┃ bill_mean ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━┩
│ string    │ float64   │
├───────────┼───────────┤
│ Torgersen │  43.92193 │
│ Torgersen │  43.92193 │
│ Torgersen │  43.92193 │
│ Torgersen │  43.92193 │
│ Torgersen │  43.92193 │
└───────────┴───────────┘

Projection with a selector

>>> import ibis.selectors as s
>>> t.select(s.numeric() & ~s.c("year")).head()
┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃
┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩
│ float64        │ float64       │ int64             │ int64       │
├────────────────┼───────────────┼───────────────────┼─────────────┤
│           39.1 │          18.7 │               181 │        3750 │
│           39.5 │          17.4 │               186 │        3800 │
│           40.3 │          18.0 │               195 │        3250 │
│            nan │           nan │              NULL │        NULL │
│           36.7 │          19.3 │               193 │        3450 │
└────────────────┴───────────────┴───────────────────┴─────────────┘

Projection + aggregation across multiple columns

>>> from ibis import _
>>> t.select(s.across(s.numeric() & ~s.c("year"), _.mean())).head()
┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃
┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩
│ float64        │ float64       │ float64           │ float64     │
├────────────────┼───────────────┼───────────────────┼─────────────┤
│       43.92193 │      17.15117 │        200.915205 │ 4201.754386 │
│       43.92193 │      17.15117 │        200.915205 │ 4201.754386 │
│       43.92193 │      17.15117 │        200.915205 │ 4201.754386 │
│       43.92193 │      17.15117 │        200.915205 │ 4201.754386 │
│       43.92193 │      17.15117 │        200.915205 │ 4201.754386 │
└────────────────┴───────────────┴───────────────────┴─────────────┘

sql(query)

Run a SQL query against a table expression.

The SQL string is backend specific

query must be valid SQL for the execution backend the expression will run against.

This restriction may be lifted in a future version of ibis.

See Table.alias for details on using named table expressions in a SQL string.

Parameters:

Name Type Description Default
query str

Query string

required

Returns:

Type Description
Table

An opaque table expression

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch(table_name="penguins")
>>> expr = t.sql("SELECT island, mean(bill_length_mm) FROM penguins GROUP BY 1 ORDER BY 2 DESC")
>>> expr
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ island    ┃ mean(bill_length_mm) ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│ string    │ float64              │
├───────────┼──────────────────────┤
│ Biscoe    │            45.257485 │
│ Dream     │            44.167742 │
│ Torgersen │            38.950980 │
└───────────┴──────────────────────┘

to_array()

View a single column table as an array.

Returns:

Type Description
Value

A single column view of a table

to_pandas(**kwargs)

Convert a table expression to a pandas DataFrame.

Parameters:

Name Type Description Default
kwargs

Same as keyword arguments to execute

{}

union(*tables, distinct=False)

Compute the set union of multiple table expressions.

The input tables must have identical schemas.

Parameters:

Name Type Description Default
*tables Table

One or more table expressions

()
distinct bool

Only return distinct rows

False

Returns:

Type Description
Table

A new table containing the union of all input tables.

See Also

ibis.union

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t1 = ibis.memtable({"a": [1, 2]})
>>> t1
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     2 │
└───────┘
>>> t2 = ibis.memtable({"a": [2, 3]})
>>> t2
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     2 │
│     3 │
└───────┘
>>> t1.union(t2)  # union all by default
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     2 │
│     2 │
│     3 │
└───────┘
>>> t1.union(t2, distinct=True).order_by("a")
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     2 │
│     3 │
└───────┘

Passing no arguments to union returns the table expression

This can be useful when you have a sequence of tables to process, and you don't know the length prior to running your program (for example, user input).

>>> t1
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     2 │
└───────┘
>>> t1.union()
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     2 │
└───────┘
>>> t1.union().equals(t1)
True

unpack(*columns)

Project the struct fields of each of columns into self.

Existing fields are retained in the projection.

Parameters:

Name Type Description Default
columns str

String column names to project into self.

()

Returns:

Type Description
Table

The child table with struct fields of each of columns projected.

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> lines = '''
...     {"name": "a", "pos": {"lat": 10.1, "lon": 30.3}}
...     {"name": "b", "pos": {"lat": 10.2, "lon": 30.2}}
...     {"name": "c", "pos": {"lat": 10.3, "lon": 30.1}}
... '''
>>> with open("/tmp/lines.json", "w") as f:
...     _ = f.write(lines)
>>> t = ibis.read_json("/tmp/lines.json")
>>> t
┏━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ name   ┃ pos                                ┃
┡━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ string │ struct<lat: float64, lon: float64> │
├────────┼────────────────────────────────────┤
│ a      │ {'lat': 10.1, 'lon': 30.3}         │
│ b      │ {'lat': 10.2, 'lon': 30.2}         │
│ c      │ {'lat': 10.3, 'lon': 30.1}         │
└────────┴────────────────────────────────────┘
>>> t.unpack("pos")
┏━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┓
┃ name   ┃ lat     ┃ lon     ┃
┡━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━┩
│ string │ float64 │ float64 │
├────────┼─────────┼─────────┤
│ a      │    10.1 │    30.3 │
│ b      │    10.2 │    30.2 │
│ c      │    10.3 │    30.1 │
└────────┴─────────┴─────────┘
See Also

StructValue.lift

view()

Create a new table expression distinct from the current one.

Use this API for any self-referencing operations like a self-join.

Returns:

Type Description
Table

Table expression

GroupedTable

An intermediate table expression to hold grouping information.

Functions

aggregate(metrics=None, **kwds)

Compute aggregates over a group by.

count(metric_name='count')

Computing the number of rows per group.

Parameters:

Name Type Description Default
metric_name str

Name to use for the row count metric

'count'

Returns:

Type Description
Table

The aggregated table

having(expr)

Add a post-aggregation result filter expr.

Expressions like x is None return bool and will not generate a SQL comparison to NULL

Parameters:

Name Type Description Default
expr ir.BooleanScalar

An expression that filters based on an aggregate value.

required

Returns:

Type Description
GroupedTable

A grouped table expression

mutate(*exprs, **kwexprs)

Return a table projection with window functions applied.

Any arguments can be functions.

Parameters:

Name Type Description Default
exprs ir.Value | Sequence[ir.Value]

List of expressions

()
kwexprs ir.Value

Expressions

{}

Examples:

>>> import ibis
>>> t = ibis.table([
...     ('foo', 'string'),
...     ('bar', 'string'),
...     ('baz', 'double'),
... ], name='t')
>>> t
UnboundTable: t
  foo string
  bar string
  baz float64
>>> expr = (t.group_by('foo')
...          .order_by(ibis.desc('bar'))
...          .mutate(qux=lambda x: x.baz.lag(), qux2=t.baz.lead()))
>>> print(expr)
r0 := UnboundTable: t
  foo string
  bar string
  baz float64
Selection[r0]
  selections:
    r0
    qux:  WindowFunction(...)
    qux2: WindowFunction(...)

Returns:

Type Description
Table

A table expression with window functions applied

order_by(expr)

Sort a grouped table expression by expr.

Notes

This API call is ignored in aggregations.

Parameters:

Name Type Description Default
expr ir.Value | Iterable[ir.Value]

Expressions to order the results by

required

Returns:

Type Description
GroupedTable

A sorted grouped GroupedTable

over(window=None, *, rows=None, range=None, group_by=None, order_by=None)

Apply a window over the input expressions.

Parameters:

Name Type Description Default
window

Window to add to the input

None
rows

Whether to use the ROWS window clause

None
range

Whether to use the RANGE window clause

None
group_by

Grouping key

None
order_by

Ordering key

None

Returns:

Type Description
GroupedTable

A new grouped table expression

select(*exprs, **kwexprs)

Project new columns out of the grouped table.

See Also

GroupedTable.mutate


Last update: August 5, 2022