162 changes: 81 additions & 81 deletions ibis/expr/types/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1123,9 +1123,9 @@ def identical_to(self, other: Value) -> ir.BooleanValue:
>>> one = ibis.literal(1)
>>> two = ibis.literal(2)
>>> two.identical_to(one + one)
┌──────────
np.True_
└──────────
┌──────┐
True
└──────┘
"""
try:
return ops.IdenticalTo(self, other).to_expr()
Expand Down Expand Up @@ -1175,19 +1175,19 @@ def group_concat(
│ 36.7 │ 19.3 │
└────────────────┴───────────────┘
>>> t.bill_length_mm.group_concat()
┌───────────────────────
'39.1,39.5,40.3,36.7'
└───────────────────────
┌─────────────────────┐
│ 39.1,39.5,40.3,36.7 │
└─────────────────────┘
>>> t.bill_length_mm.group_concat(sep=": ")
┌──────────────────────────
'39.1: 39.5: 40.3: 36.7'
└──────────────────────────
┌────────────────────────┐
│ 39.1: 39.5: 40.3: 36.7 │
└────────────────────────┘
>>> t.bill_length_mm.group_concat(sep=": ", where=t.bill_depth_mm > 18)
┌──────────────
'39.1: 36.7'
└──────────────
┌────────────┐
│ 39.1: 36.7 │
└────────────┘
"""
return ops.GroupConcat(
self,
Expand Down Expand Up @@ -1602,13 +1602,13 @@ def approx_nunique(self, where: ir.BooleanValue | None = None) -> ir.IntegerScal
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.body_mass_g.approx_nunique()
┌──────────────
np.int64(94)
└──────────────
┌────┐
94
└────┘
>>> t.body_mass_g.approx_nunique(where=t.species == "Adelie")
┌──────────────
np.int64(55)
└──────────────
┌────┐
55
└────┘
"""
return ops.ApproxCountDistinct(
self, where=self._bind_to_parent_table(where)
Expand Down Expand Up @@ -1644,13 +1644,13 @@ def approx_median(self, where: ir.BooleanValue | None = None) -> Scalar:
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.body_mass_g.approx_median()
┌────────────────
np.int64(4030)
└────────────────
┌──────┐
│ 4030 │
└──────┘
>>> t.body_mass_g.approx_median(where=t.species == "Chinstrap")
┌────────────────
np.int64(3700)
└────────────────
┌──────┐
│ 3700 │
└──────┘
"""
return ops.ApproxMedian(self, where=self._bind_to_parent_table(where)).to_expr()

Expand All @@ -1673,13 +1673,13 @@ def mode(self, where: ir.BooleanValue | None = None) -> Scalar:
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.body_mass_g.mode()
┌────────────────
np.int64(3800)
└────────────────
┌──────┐
│ 3800 │
└──────┘
>>> t.body_mass_g.mode(where=(t.species == "Gentoo") & (t.sex == "male"))
┌────────────────
np.int64(5550)
└────────────────
┌──────┐
│ 5550 │
└──────┘
"""
return ops.Mode(self, where=self._bind_to_parent_table(where)).to_expr()

Expand All @@ -1702,13 +1702,13 @@ def max(self, where: ir.BooleanValue | None = None) -> Scalar:
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.body_mass_g.max()
┌────────────────
np.int64(6300)
└────────────────
┌──────┐
│ 6300 │
└──────┘
>>> t.body_mass_g.max(where=t.species == "Chinstrap")
┌────────────────
np.int64(4800)
└────────────────
┌──────┐
│ 4800 │
└──────┘
"""
return ops.Max(self, where=self._bind_to_parent_table(where)).to_expr()

Expand All @@ -1731,13 +1731,13 @@ def min(self, where: ir.BooleanValue | None = None) -> Scalar:
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.body_mass_g.min()
┌────────────────
np.int64(2700)
└────────────────
┌──────┐
│ 2700 │
└──────┘
>>> t.body_mass_g.min(where=t.species == "Adelie")
┌────────────────
np.int64(2850)
└────────────────
┌──────┐
│ 2850 │
└──────┘
"""
return ops.Min(self, where=self._bind_to_parent_table(where)).to_expr()

Expand All @@ -1762,13 +1762,13 @@ def argmax(self, key: ir.Value, where: ir.BooleanValue | None = None) -> Scalar:
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.species.argmax(t.body_mass_g)
┌──────────
'Gentoo'
└──────────
┌────────┐
│ Gentoo │
└────────┘
>>> t.species.argmax(t.body_mass_g, where=t.island == "Dream")
┌─────────────
'Chinstrap'
└─────────────
┌───────────┐
│ Chinstrap │
└───────────┘
"""
return ops.ArgMax(
self,
Expand Down Expand Up @@ -1797,14 +1797,14 @@ def argmin(self, key: ir.Value, where: ir.BooleanValue | None = None) -> Scalar:
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.species.argmin(t.body_mass_g)
┌─────────────
'Chinstrap'
└─────────────
┌───────────┐
│ Chinstrap │
└───────────┘
>>> t.species.argmin(t.body_mass_g, where=t.island == "Biscoe")
┌──────────
'Adelie'
└──────────
┌────────┐
│ Adelie │
└────────┘
"""
return ops.ArgMin(
self,
Expand Down Expand Up @@ -1835,9 +1835,9 @@ def median(self, where: ir.BooleanValue | None = None) -> Scalar:
Compute the median of `bill_depth_mm`
>>> t.bill_depth_mm.median()
┌──────────────────
np.float64(17.3)
└──────────────────
┌──────┐
│ 17.3 │
└──────┘
>>> t.group_by(t.species).agg(median_bill_depth=t.bill_depth_mm.median()).order_by(
... ibis.desc("median_bill_depth")
... )
Expand Down Expand Up @@ -1901,9 +1901,9 @@ def quantile(
Compute the 99th percentile of `bill_depth`
>>> t.bill_depth_mm.quantile(0.99)
┌──────────────────
np.float64(21.1)
└──────────────────
┌──────┐
│ 21.1 │
└──────┘
>>> t.group_by(t.species).agg(p99_bill_depth=t.bill_depth_mm.quantile(0.99)).order_by(
... ibis.desc("p99_bill_depth")
... )
Expand Down Expand Up @@ -1960,13 +1960,13 @@ def nunique(self, where: ir.BooleanValue | None = None) -> ir.IntegerScalar:
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.body_mass_g.nunique()
┌──────────────
np.int64(94)
└──────────────
┌────┐
94
└────┘
>>> t.body_mass_g.nunique(where=t.species == "Adelie")
┌──────────────
np.int64(55)
└──────────────
┌────┐
55
└────┘
"""
return ops.CountDistinct(
self, where=self._bind_to_parent_table(where)
Expand Down Expand Up @@ -2154,13 +2154,13 @@ def first(
│ d │
└────────┘
>>> t.chars.first()
┌─────
'a'
└─────
┌───┐
a
└───┘
>>> t.chars.first(where=t.chars != "a")
┌─────
'b'
└─────
┌───┐
b
└───┘
"""
return ops.First(
self,
Expand Down Expand Up @@ -2207,13 +2207,13 @@ def last(
│ d │
└────────┘
>>> t.chars.last()
┌─────
'd'
└─────
┌───┐
d
└───┘
>>> t.chars.last(where=t.chars != "d")
┌─────
'c'
└─────
┌───┐
c
└───┘
"""
return ops.Last(
self,
Expand Down Expand Up @@ -2416,9 +2416,9 @@ def null(type: dt.DataType | str | None = None) -> Value:
│ None │
└──────┘
>>> ibis.null(str).upper().isnull()
┌──────────
np.True_
└──────────
┌──────┐
True
└──────┘
"""
if type is None:
type = dt.null
Expand Down
6 changes: 3 additions & 3 deletions ibis/expr/types/geospatial.py
Original file line number Diff line number Diff line change
Expand Up @@ -803,9 +803,9 @@ def length(self) -> ir.FloatingValue:
>>> line = shapely.LineString([[0, 0], [1, 0], [1, 1]])
>>> line_lit = ibis.literal(line, type="geometry")
>>> line_lit.length()
┌─────────────────
np.float64(2.0)
└─────────────────
┌─────┐
│ 2.0 │
└─────┘
>>> t = ibis.examples.zones.fetch()
>>> t.geom.length()
┏━━━━━━━━━━━━━━━━━┓
Expand Down
84 changes: 42 additions & 42 deletions ibis/expr/types/logical.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,17 +322,17 @@ def any(self, where: BooleanValue | None = None) -> BooleanValue:
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"arr": [1, 2, 3, None]})
>>> (t.arr > 2).any()
┌──────────
np.True_
└──────────
┌──────┐
True
└──────┘
>>> (t.arr > 4).any()
┌───────────
np.False_
└───────────
┌───────┐
False
└───────┘
>>> (t.arr == None).any(where=t.arr != None)
┌───────────
np.False_
└───────────
┌───────┐
False
└───────┘
"""
from ibis.common.deferred import Call, Deferred, _

Expand Down Expand Up @@ -375,18 +375,18 @@ def notany(self, where: BooleanValue | None = None) -> BooleanValue:
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"arr": [1, 2, 3, 4]})
>>> (t.arr > 1).notany()
┌───────────
np.False_
└───────────
┌───────┐
False
└───────┘
>>> (t.arr > 4).notany()
┌──────────
np.True_
└──────────
┌──────┐
True
└──────┘
>>> m = ibis.memtable({"arr": [True, True, True, False]})
>>> (t.arr == None).notany(where=t.arr != None)
┌──────────
np.True_
└──────────
┌──────┐
True
└──────┘
"""
return ~self.any(where=where)

Expand All @@ -409,21 +409,21 @@ def all(self, where: BooleanValue | None = None) -> BooleanScalar:
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"arr": [1, 2, 3, 4]})
>>> (t.arr >= 1).all()
┌──────────
np.True_
└──────────
┌──────┐
True
└──────┘
>>> (t.arr > 2).all()
┌───────────
np.False_
└───────────
┌───────┐
False
└───────┘
>>> (t.arr == 2).all(where=t.arr == 2)
┌──────────
np.True_
└──────────
┌──────┐
True
└──────┘
>>> (t.arr == 2).all(where=t.arr >= 2)
┌───────────
np.False_
└───────────
┌───────┐
False
└───────┘
"""
return ops.All(self, where=self._bind_to_parent_table(where)).to_expr()

Expand All @@ -446,21 +446,21 @@ def notall(self, where: BooleanValue | None = None) -> BooleanScalar:
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"arr": [1, 2, 3, 4]})
>>> (t.arr >= 1).notall()
┌───────────
np.False_
└───────────
┌───────┐
False
└───────┘
>>> (t.arr > 2).notall()
┌──────────
np.True_
└──────────
┌──────┐
True
└──────┘
>>> (t.arr == 2).notall(where=t.arr == 2)
┌───────────
np.False_
└───────────
┌───────┐
False
└───────┘
>>> (t.arr == 2).notall(where=t.arr >= 2)
┌──────────
np.True_
└──────────
┌──────┐
True
└──────┘
"""
return ~self.all(where=where)

Expand Down
12 changes: 7 additions & 5 deletions ibis/expr/types/pretty.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ def _(dtype, values, **fmt_kwargs):
import shapely

return _format_nested(
[None if v is None else shapely.from_wkb(v) for v in values], **fmt_kwargs
[shapely.from_wkb(v) if isinstance(v, (bytes, str)) else v for v in values],
**fmt_kwargs,
)


Expand Down Expand Up @@ -288,13 +289,14 @@ def _to_rich_scalar(
max_string: int | None = None,
max_depth: int | None = None,
) -> Pretty:
scalar = Pretty(
expr.execute(),
value = format_values(
expr.type(),
[expr.execute()],
max_length=max_length or ibis.options.repr.interactive.max_length,
max_string=max_string or ibis.options.repr.interactive.max_string,
max_depth=max_depth or ibis.options.repr.interactive.max_depth,
)
return Panel(scalar, expand=False, box=box.SQUARE)
)[0]
return Panel(value, expand=False, box=box.SQUARE)


def _to_rich_table(
Expand Down
66 changes: 33 additions & 33 deletions ibis/expr/types/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -1238,13 +1238,13 @@ def distinct(
>>> expr = t.distinct(on=["species", "island", "year", "bill_length_mm"], keep=None)
>>> expr.count()
┌───────────────
np.int64(273)
└───────────────
┌─────┐
│ 273 │
└─────┘
>>> t.count()
┌───────────────
np.int64(344)
└───────────────
┌─────┐
│ 344 │
└─────┘
You can pass [`selectors`](./selectors.qmd) to `on`
Expand Down Expand Up @@ -2608,13 +2608,13 @@ def nunique(self, where: ir.BooleanValue | None = None) -> ir.IntegerScalar:
│ bar │
└────────┘
>>> t.nunique()
┌─────────────
np.int64(2)
└─────────────
┌───┐
2
└───┘
>>> t.nunique(t.a != "foo")
┌─────────────
np.int64(1)
└─────────────
┌───┐
1
└───┘
"""
if where is not None:
(where,) = bind(self, where)
Expand Down Expand Up @@ -2649,13 +2649,13 @@ def count(self, where: ir.BooleanValue | None = None) -> ir.IntegerScalar:
│ baz │
└────────┘
>>> t.count()
┌─────────────
np.int64(3)
└─────────────
┌───┐
3
└───┘
>>> t.count(t.a != "foo")
┌─────────────
np.int64(2)
└─────────────
┌───┐
2
└───┘
>>> type(t.count())
<class 'ibis.expr.types.numeric.IntegerScalar'>
"""
Expand Down Expand Up @@ -2709,17 +2709,17 @@ def drop_null(
│ … │ … │ … │ … │ … │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴───┘
>>> t.count()
┌───────────────
np.int64(344)
└───────────────
┌─────┐
│ 344 │
└─────┘
>>> t.drop_null(["bill_length_mm", "body_mass_g"]).count()
┌───────────────
np.int64(342)
└───────────────
┌─────┐
│ 342 │
└─────┘
>>> t.drop_null(how="all").count() # no rows where all columns are null
┌───────────────
np.int64(344)
└───────────────
┌─────┐
│ 344 │
└─────┘
"""
if subset is not None:
subset = self.bind(subset)
Expand Down Expand Up @@ -3353,9 +3353,9 @@ def cross_join(
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t.count()
┌───────────────
np.int64(344)
└───────────────
┌─────┐
│ 344 │
└─────┘
>>> agg = t.drop("year").agg(s.across(s.numeric(), _.mean()))
>>> expr = t.cross_join(agg)
>>> expr
Expand Down Expand Up @@ -3390,9 +3390,9 @@ def cross_join(
'flipper_length_mm_right',
'body_mass_g_right']
>>> expr.count()
┌───────────────
np.int64(344)
└───────────────
┌─────┐
│ 344 │
└─────┘
"""
from ibis.expr.types.joins import Join

Expand Down
6 changes: 3 additions & 3 deletions ibis/expr/types/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1695,9 +1695,9 @@ def levenshtein(self, other: StringValue) -> ir.IntegerValue:
>>> ibis.options.interactive = True
>>> s = ibis.literal("kitten")
>>> s.levenshtein("sitting")
┌─────────────
np.int64(3)
└─────────────
┌───┐
3
└───┘
"""
return ops.Levenshtein(self, other).to_expr()

Expand Down
18 changes: 9 additions & 9 deletions ibis/expr/types/temporal.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ def delta(
>>> start = ibis.time("01:58:00")
>>> end = ibis.time("23:59:59")
>>> end.delta(start, "hour")
┌──────────────
np.int64(22)
└──────────────
┌────┐
22
└────┘
>>> data = '''tpep_pickup_datetime,tpep_dropoff_datetime
... 2016-02-01T00:23:56,2016-02-01T00:42:28
... 2016-02-01T00:12:14,2016-02-01T00:21:41
Expand Down Expand Up @@ -445,9 +445,9 @@ def delta(
>>> start = ibis.date("1992-09-30")
>>> end = ibis.date("1992-10-01")
>>> end.delta(start, "day")
┌─────────────
np.int64(1)
└─────────────
┌───┐
1
└───┘
>>> prez = ibis.examples.presidential.fetch()
>>> prez.mutate(
... years_in_office=prez.end.delta(prez.start, "year"),
Expand Down Expand Up @@ -779,9 +779,9 @@ def delta(
>>> start = ibis.time("01:58:00")
>>> end = ibis.time("23:59:59")
>>> end.delta(start, "hour")
┌──────────────
np.int64(22)
└──────────────
┌────┐
22
└────┘
>>> data = '''tpep_pickup_datetime,tpep_dropoff_datetime
... 2016-02-01T00:23:56,2016-02-01T00:42:28
... 2016-02-01T00:12:14,2016-02-01T00:21:41
Expand Down