Skip to content

Complex Type Expressions

These APIs are available on arrays, maps and structs.

ArrayValue

Bases: Value

Source code in ibis/expr/types/arrays.py
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
@public
class ArrayValue(Value):
    def length(self) -> ir.IntegerValue:
        """Compute the length of an array.

        Returns
        -------
        IntegerValue
            The integer length of each element of `self`

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"a": [[7, 42], [3], None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ a                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [7, 42]              │
        │ [3]                  │
        │ NULL                 │
        └──────────────────────┘
        >>> t.a.length()
        ┏━━━━━━━━━━━━━━━━┓
        ┃ ArrayLength(a) ┃
        ┡━━━━━━━━━━━━━━━━┩
        │ int64          │
        ├────────────────┤
        │              2 │
        │              1 │
        │           NULL │
        └────────────────┘
        """
        return ops.ArrayLength(self).to_expr()

    def __getitem__(self, index: int | ir.IntegerValue | slice) -> ir.Value:
        """Extract one or more elements of `self`.

        Parameters
        ----------
        index
            Index into `array`

        Returns
        -------
        Value
            - If `index` is an [`int`][int] or
              [`IntegerValue`][ibis.expr.types.IntegerValue] then the return
              type is the element type of `self`.
            - If `index` is a [`slice`][slice] then the return type is the same
              type as the input.

        Examples
        --------
        Extract a single element

        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"a": [[7, 42], [3], None]})
        >>> t.a[0]
        ┏━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayIndex(a, 0) ┃
        ┡━━━━━━━━━━━━━━━━━━┩
        │ int64            │
        ├──────────────────┤
        │                7 │
        │                3 │
        │             NULL │
        └──────────────────┘

        Extract a range of elements

        >>> t = ibis.memtable({"a": [[7, 42, 72], [3] * 5, None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ a                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [7, 42, ... +1]      │
        │ [3, 3, ... +3]       │
        │ NULL                 │
        └──────────────────────┘
        >>> t.a[1:2]
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArraySlice(a, 1, 2)  ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [42]                 │
        │ [3]                  │
        │ NULL                 │
        └──────────────────────┘
        """
        if isinstance(index, slice):
            start = index.start
            stop = index.stop
            step = index.step

            if step is not None and step != 1:
                raise NotImplementedError('step can only be 1')

            op = ops.ArraySlice(self, start if start is not None else 0, stop)
        else:
            op = ops.ArrayIndex(self, index)
        return op.to_expr()

    def concat(self, other: ArrayValue, *args: ArrayValue) -> ArrayValue:
        """Concatenate this array with one or more arrays.

        Parameters
        ----------
        other
            Other array to concat with `self`
        args
            Other arrays to concat with `self`

        Returns
        -------
        ArrayValue
            `self` concatenated with `other` and `args`

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"a": [[7], [3] , None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ a                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [7]                  │
        │ [3]                  │
        │ NULL                 │
        └──────────────────────┘
        >>> t.a.concat(t.a)
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayConcat()        ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [7, 7]               │
        │ [3, 3]               │
        │ NULL                 │
        └──────────────────────┘
        >>> t.a.concat(ibis.literal([4], type="array<int64>"))
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayConcat()        ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [7, 4]               │
        │ [3, 4]               │
        │ [4]                  │
        └──────────────────────┘

        `concat` is also available using the `+` operator

        >>> [1] + t.a
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayConcat()        ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [1, 7]               │
        │ [1, 3]               │
        │ [1]                  │
        └──────────────────────┘
        >>> t.a + [1]
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayConcat()        ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [7, 1]               │
        │ [3, 1]               │
        │ [1]                  │
        └──────────────────────┘
        """
        return ops.ArrayConcat((self, other, *args)).to_expr()

    def __add__(self, other: ArrayValue) -> ArrayValue:
        return self.concat(other)

    def __radd__(self, other: ArrayValue) -> ArrayValue:
        return ops.ArrayConcat((other, self)).to_expr()

    def repeat(self, n: int | ir.IntegerValue) -> ArrayValue:
        """Repeat this array `n` times.

        Parameters
        ----------
        n
            Number of times to repeat `self`.

        Returns
        -------
        ArrayValue
            `self` repeated `n` times

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"a": [[7], [3] , None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ a                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [7]                  │
        │ [3]                  │
        │ NULL                 │
        └──────────────────────┘
        >>> t.a.repeat(2)
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayRepeat(a, 2)    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [7, 7]               │
        │ [3, 3]               │
        │ []                   │
        └──────────────────────┘

        `repeat` is also available using the `*` operator

        >>> 2 * t.a
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayRepeat(a, 2)    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [7, 7]               │
        │ [3, 3]               │
        │ []                   │
        └──────────────────────┘
        """
        return ops.ArrayRepeat(self, n).to_expr()

    __mul__ = __rmul__ = repeat

    def unnest(self) -> ir.Value:
        """Flatten an array into a column.

        !!! note "This operation changes the cardinality of the result"

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"a": [[7, 42], [3, 3] , None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ a                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [7, 42]              │
        │ [3, 3]               │
        │ NULL                 │
        └──────────────────────┘
        >>> t.a.unnest()
        ┏━━━━━━━┓
        ┃ a     ┃
        ┡━━━━━━━┩
        │ int64 │
        ├───────┤
        │     7 │
        │    42 │
        │     3 │
        │     3 │
        └───────┘

        Returns
        -------
        ir.Value
            Unnested array
        """
        expr = ops.Unnest(self).to_expr()
        try:
            return expr.name(self.get_name())
        except com.ExpressionError:
            return expr

    def join(self, sep: str | ir.StringValue) -> ir.StringValue:
        """Join the elements of this array expression with `sep`.

        Parameters
        ----------
        sep
            Separator to use for joining array elements

        Returns
        -------
        StringValue
            Elements of `self` joined with `sep`

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"arr": [["a", "b", "c"], None, [], ["b", None]]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ arr                  ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<string>        │
        ├──────────────────────┤
        │ ['a', 'b', ... +1]   │
        │ NULL                 │
        │ []                   │
        │ ['b', None]          │
        └──────────────────────┘
        >>> t.arr.join("|")
        ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayStringJoin('|', arr) ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ string                    │
        ├───────────────────────────┤
        │ a|b|c                     │
        │ NULL                      │
        │ NULL                      │
        │ b                         │
        └───────────────────────────┘

        See Also
        --------
        [`StringValue.join`][ibis.expr.types.strings.StringValue.join]
        """
        return ops.ArrayStringJoin(sep, self).to_expr()

    def map(self, func: Callable[[ir.Value], ir.Value]) -> ir.ArrayValue:
        """Apply a callable `func` to each element of this array expression.

        Parameters
        ----------
        func
            Function to apply to each element of this array

        Returns
        -------
        ArrayValue
            `func` applied to every element of this array expression.

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"a": [[1, None, 2], [4], []]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ a                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [1, None, ... +1]    │
        │ [4]                  │
        │ []                   │
        └──────────────────────┘
        >>> t.a.map(lambda x: (x + 100).cast("float"))
        ┏━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayMap(a)           ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<float64>        │
        ├───────────────────────┤
        │ [101.0, None, ... +1] │
        │ [104.0]               │
        │ []                    │
        └───────────────────────┘
        """
        return ops.ArrayMap(self, func=func).to_expr()

    def filter(
        self, predicate: Callable[[ir.Value], bool | ir.BooleanValue]
    ) -> ir.ArrayValue:
        """Filter array elements using `predicate`.

        Parameters
        ----------
        predicate
            Function to use to filter array elements

        Returns
        -------
        ArrayValue
            Array elements filtered using `predicate`

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"a": [[1, None, 2], [4], []]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ a                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [1, None, ... +1]    │
        │ [4]                  │
        │ []                   │
        └──────────────────────┘
        >>> t.a.filter(lambda x: x > 1)
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayFilter(a)       ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [2]                  │
        │ [4]                  │
        │ []                   │
        └──────────────────────┘
        """
        return ops.ArrayFilter(self, func=predicate).to_expr()

    def contains(self, other: ir.Value) -> ir.BooleanValue:
        """Return whether the array contains `other`.

        Parameters
        ----------
        other
            Ibis expression to check for existence of in `self`

        Returns
        -------
        BooleanValue
            Whether `other` is contained in `self`

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"arr": [[1], [], [42, 42], None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ arr                  ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [1]                  │
        │ []                   │
        │ [42, 42]             │
        │ NULL                 │
        └──────────────────────┘
        >>> t.arr.contains(42)
        ┏━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayContains(arr, 42) ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ boolean                │
        ├────────────────────────┤
        │ False                  │
        │ False                  │
        │ True                   │
        │ NULL                   │
        └────────────────────────┘
        >>> t.arr.contains(None)
        ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayContains(arr, None) ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ boolean                  │
        ├──────────────────────────┤
        │ NULL                     │
        │ NULL                     │
        │ NULL                     │
        │ NULL                     │
        └──────────────────────────┘
        """
        return ops.ArrayContains(self, other).to_expr()

    def index(self, other: ir.Value) -> ir.IntegerValue:
        """Return the position of `other` in an array.

        Parameters
        ----------
        other
            Ibis expression to existence of in `self`

        Returns
        -------
        BooleanValue
            The position of `other` in `self`

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"arr": [[1], [], [42, 42], None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ arr                  ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [1]                  │
        │ []                   │
        │ [42, 42]             │
        │ NULL                 │
        └──────────────────────┘
        >>> t.arr.index(42)
        ┏━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayPosition(arr, 42) ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ int64                  │
        ├────────────────────────┤
        │                     -1 │
        │                     -1 │
        │                      0 │
        │                   NULL │
        └────────────────────────┘
        >>> t.arr.index(800)
        ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayPosition(arr, 800) ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ int64                   │
        ├─────────────────────────┤
        │                      -1 │
        │                      -1 │
        │                      -1 │
        │                    NULL │
        └─────────────────────────┘
        >>> t.arr.index(None)
        ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayPosition(arr, None) ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ int64                    │
        ├──────────────────────────┤
        │                     NULL │
        │                     NULL │
        │                     NULL │
        │                     NULL │
        └──────────────────────────┘
        """
        return ops.ArrayPosition(self, other).to_expr()

    def remove(self, other: ir.Value) -> ir.ArrayValue:
        """Remove `other` from `self`.

        Parameters
        ----------
        other
            Element to remove from `self`.

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"arr": [[3, 2], [], [42, 2], [2, 2], None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ arr                  ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [3, 2]               │
        │ []                   │
        │ [42, 2]              │
        │ [2, 2]               │
        │ NULL                 │
        └──────────────────────┘
        >>> t.arr.remove(2)
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayRemove(arr, 2)  ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [3]                  │
        │ []                   │
        │ [42]                 │
        │ []                   │
        │ NULL                 │
        └──────────────────────┘
        """
        return ops.ArrayRemove(self, other).to_expr()

    def unique(self) -> ir.ArrayValue:
        """Return the unique values in an array.

        !!! note "Element ordering in array may not be retained."

        Returns
        -------
        ArrayValue
            Unique values in an array

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"arr": [[1, 3, 3], [], [42, 42], None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ arr                  ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [1, 3, ... +1]       │
        │ []                   │
        │ [42, 42]             │
        │ NULL                 │
        └──────────────────────┘
        >>> t.arr.unique()
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayDistinct(arr)   ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [3, 1]               │
        │ []                   │
        │ [42]                 │
        │ NULL                 │
        └──────────────────────┘
        """
        return ops.ArrayDistinct(self).to_expr()

    def sort(self) -> ir.ArrayValue:
        """Sort the elements in an array.

        Returns
        -------
        ArrayValue
            Sorted values in an array

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"arr": [[3, 2], [], [42, 42], None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ arr                  ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [3, 2]               │
        │ []                   │
        │ [42, 42]             │
        │ NULL                 │
        └──────────────────────┘
        >>> t.arr.sort()
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArraySort(arr)       ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │
        ├──────────────────────┤
        │ [2, 3]               │
        │ []                   │
        │ [42, 42]             │
        │ NULL                 │
        └──────────────────────┘
        """
        return ops.ArraySort(self).to_expr()

    def union(self, other: ir.ArrayValue) -> ir.ArrayValue:
        """Union two arrays.

        Parameters
        ----------
        other
            Another array to union with `self`

        Returns
        -------
        ArrayValue
            Unioned arrays

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"arr1": [[3, 2], [], None], "arr2": [[1, 3], [None], [5]]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ arr1                 ┃ arr2                 ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │ array<int64>         │
        ├──────────────────────┼──────────────────────┤
        │ [3, 2]               │ [1, 3]               │
        │ []                   │ [None]               │
        │ NULL                 │ [5]                  │
        └──────────────────────┴──────────────────────┘
        >>> t.arr1.union(t.arr2)
        ┏━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayUnion(arr1, arr2) ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>           │
        ├────────────────────────┤
        │ [1, 2, ... +1]         │
        │ []                     │
        │ [5]                    │
        └────────────────────────┘
        >>> t.arr1.union(t.arr2).contains(3)
        ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayContains(ArrayUnion(arr1, arr2), 3) ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ boolean                                  │
        ├──────────────────────────────────────────┤
        │ True                                     │
        │ False                                    │
        │ False                                    │
        └──────────────────────────────────────────┘
        """
        return ops.ArrayUnion(self, other).to_expr()

    def zip(self, other: ir.Array, *others: ir.Array) -> ir.Array:
        """Zip two or more arrays together.

        Parameters
        ----------
        other
            Another array to zip with `self`
        others
            Additional arrays to zip with `self`

        Returns
        -------
        Array
            Array of structs where each struct field is an element of each input
            array.

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({"numbers": [[3, 2], [], None], "strings": [["a", "c"], None, ["e"]]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ numbers              ┃ strings              ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<int64>         │ array<string>        │
        ├──────────────────────┼──────────────────────┤
        │ [3, 2]               │ ['a', 'c']           │
        │ []                   │ NULL                 │
        │ NULL                 │ ['e']                │
        └──────────────────────┴──────────────────────┘
        >>> expr = t.numbers.zip(t.strings)
        >>> expr
        ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayZip()                           ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<struct<f1: int64, f2: string>> │
        ├──────────────────────────────────────┤
        │ [{...}, {...}]                       │
        │ []                                   │
        │ [{...}]                              │
        └──────────────────────────────────────┘
        >>> expr.unnest()
        ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ ArrayZip()                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ struct<f1: int64, f2: string> │
        ├───────────────────────────────┤
        │ {'f1': 3, 'f2': 'a'}          │
        │ {'f1': 2, 'f2': 'c'}          │
        │ {'f1': None, 'f2': 'e'}       │
        └───────────────────────────────┘
        """

        return ops.ArrayZip((self, other, *others)).to_expr()

Functions

concat(other, *args)

Concatenate this array with one or more arrays.

Parameters:

Name Type Description Default
other ArrayValue

Other array to concat with self

required
args ArrayValue

Other arrays to concat with self

()

Returns:

Type Description
ArrayValue

self concatenated with other and args

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"a": [[7], [3] , None]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ a                    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [7]                  │
│ [3]                  │
│ NULL                 │
└──────────────────────┘
>>> t.a.concat(t.a)
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayConcat()        ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [7, 7]               │
│ [3, 3]               │
│ NULL                 │
└──────────────────────┘
>>> t.a.concat(ibis.literal([4], type="array<int64>"))
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayConcat()        ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [7, 4]               │
│ [3, 4]               │
│ [4]                  │
└──────────────────────┘

concat is also available using the + operator

>>> [1] + t.a
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayConcat()        ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [1, 7]               │
│ [1, 3]               │
│ [1]                  │
└──────────────────────┘
>>> t.a + [1]
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayConcat()        ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [7, 1]               │
│ [3, 1]               │
│ [1]                  │
└──────────────────────┘
Source code in ibis/expr/types/arrays.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
def concat(self, other: ArrayValue, *args: ArrayValue) -> ArrayValue:
    """Concatenate this array with one or more arrays.

    Parameters
    ----------
    other
        Other array to concat with `self`
    args
        Other arrays to concat with `self`

    Returns
    -------
    ArrayValue
        `self` concatenated with `other` and `args`

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"a": [[7], [3] , None]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ a                    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [7]                  │
    │ [3]                  │
    │ NULL                 │
    └──────────────────────┘
    >>> t.a.concat(t.a)
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayConcat()        ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [7, 7]               │
    │ [3, 3]               │
    │ NULL                 │
    └──────────────────────┘
    >>> t.a.concat(ibis.literal([4], type="array<int64>"))
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayConcat()        ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [7, 4]               │
    │ [3, 4]               │
    │ [4]                  │
    └──────────────────────┘

    `concat` is also available using the `+` operator

    >>> [1] + t.a
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayConcat()        ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [1, 7]               │
    │ [1, 3]               │
    │ [1]                  │
    └──────────────────────┘
    >>> t.a + [1]
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayConcat()        ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [7, 1]               │
    │ [3, 1]               │
    │ [1]                  │
    └──────────────────────┘
    """
    return ops.ArrayConcat((self, other, *args)).to_expr()

contains(other)

Return whether the array contains other.

Parameters:

Name Type Description Default
other ir.Value

Ibis expression to check for existence of in self

required

Returns:

Type Description
BooleanValue

Whether other is contained in self

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"arr": [[1], [], [42, 42], None]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ arr                  ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [1]                  │
│ []                   │
│ [42, 42]             │
│ NULL                 │
└──────────────────────┘
>>> t.arr.contains(42)
┏━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayContains(arr, 42) ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━┩
│ boolean                │
├────────────────────────┤
│ False                  │
│ False                  │
│ True                   │
│ NULL                   │
└────────────────────────┘
>>> t.arr.contains(None)
┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayContains(arr, None) ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ boolean                  │
├──────────────────────────┤
│ NULL                     │
│ NULL                     │
│ NULL                     │
│ NULL                     │
└──────────────────────────┘
Source code in ibis/expr/types/arrays.py
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
def contains(self, other: ir.Value) -> ir.BooleanValue:
    """Return whether the array contains `other`.

    Parameters
    ----------
    other
        Ibis expression to check for existence of in `self`

    Returns
    -------
    BooleanValue
        Whether `other` is contained in `self`

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"arr": [[1], [], [42, 42], None]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ arr                  ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [1]                  │
    │ []                   │
    │ [42, 42]             │
    │ NULL                 │
    └──────────────────────┘
    >>> t.arr.contains(42)
    ┏━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayContains(arr, 42) ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ boolean                │
    ├────────────────────────┤
    │ False                  │
    │ False                  │
    │ True                   │
    │ NULL                   │
    └────────────────────────┘
    >>> t.arr.contains(None)
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayContains(arr, None) ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ boolean                  │
    ├──────────────────────────┤
    │ NULL                     │
    │ NULL                     │
    │ NULL                     │
    │ NULL                     │
    └──────────────────────────┘
    """
    return ops.ArrayContains(self, other).to_expr()

filter(predicate)

Filter array elements using predicate.

Parameters:

Name Type Description Default
predicate Callable[[ir.Value], bool | ir.BooleanValue]

Function to use to filter array elements

required

Returns:

Type Description
ArrayValue

Array elements filtered using predicate

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"a": [[1, None, 2], [4], []]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ a                    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [1, None, ... +1]    │
│ [4]                  │
│ []                   │
└──────────────────────┘
>>> t.a.filter(lambda x: x > 1)
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayFilter(a)       ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [2]                  │
│ [4]                  │
│ []                   │
└──────────────────────┘
Source code in ibis/expr/types/arrays.py
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
def filter(
    self, predicate: Callable[[ir.Value], bool | ir.BooleanValue]
) -> ir.ArrayValue:
    """Filter array elements using `predicate`.

    Parameters
    ----------
    predicate
        Function to use to filter array elements

    Returns
    -------
    ArrayValue
        Array elements filtered using `predicate`

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"a": [[1, None, 2], [4], []]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ a                    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [1, None, ... +1]    │
    │ [4]                  │
    │ []                   │
    └──────────────────────┘
    >>> t.a.filter(lambda x: x > 1)
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayFilter(a)       ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [2]                  │
    │ [4]                  │
    │ []                   │
    └──────────────────────┘
    """
    return ops.ArrayFilter(self, func=predicate).to_expr()

index(other)

Return the position of other in an array.

Parameters:

Name Type Description Default
other ir.Value

Ibis expression to existence of in self

required

Returns:

Type Description
BooleanValue

The position of other in self

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"arr": [[1], [], [42, 42], None]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ arr                  ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [1]                  │
│ []                   │
│ [42, 42]             │
│ NULL                 │
└──────────────────────┘
>>> t.arr.index(42)
┏━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayPosition(arr, 42) ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━┩
│ int64                  │
├────────────────────────┤
│                     -1 │
│                     -1 │
│                      0 │
│                   NULL │
└────────────────────────┘
>>> t.arr.index(800)
┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayPosition(arr, 800) ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ int64                   │
├─────────────────────────┤
│                      -1 │
│                      -1 │
│                      -1 │
│                    NULL │
└─────────────────────────┘
>>> t.arr.index(None)
┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayPosition(arr, None) ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ int64                    │
├──────────────────────────┤
│                     NULL │
│                     NULL │
│                     NULL │
│                     NULL │
└──────────────────────────┘
Source code in ibis/expr/types/arrays.py
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
def index(self, other: ir.Value) -> ir.IntegerValue:
    """Return the position of `other` in an array.

    Parameters
    ----------
    other
        Ibis expression to existence of in `self`

    Returns
    -------
    BooleanValue
        The position of `other` in `self`

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"arr": [[1], [], [42, 42], None]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ arr                  ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [1]                  │
    │ []                   │
    │ [42, 42]             │
    │ NULL                 │
    └──────────────────────┘
    >>> t.arr.index(42)
    ┏━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayPosition(arr, 42) ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ int64                  │
    ├────────────────────────┤
    │                     -1 │
    │                     -1 │
    │                      0 │
    │                   NULL │
    └────────────────────────┘
    >>> t.arr.index(800)
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayPosition(arr, 800) ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ int64                   │
    ├─────────────────────────┤
    │                      -1 │
    │                      -1 │
    │                      -1 │
    │                    NULL │
    └─────────────────────────┘
    >>> t.arr.index(None)
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayPosition(arr, None) ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ int64                    │
    ├──────────────────────────┤
    │                     NULL │
    │                     NULL │
    │                     NULL │
    │                     NULL │
    └──────────────────────────┘
    """
    return ops.ArrayPosition(self, other).to_expr()

join(sep)

Join the elements of this array expression with sep.

Parameters:

Name Type Description Default
sep str | ir.StringValue

Separator to use for joining array elements

required

Returns:

Type Description
StringValue

Elements of self joined with sep

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"arr": [["a", "b", "c"], None, [], ["b", None]]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ arr                  ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<string>        │
├──────────────────────┤
│ ['a', 'b', ... +1]   │
│ NULL                 │
│ []                   │
│ ['b', None]          │
└──────────────────────┘
>>> t.arr.join("|")
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayStringJoin('|', arr) ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ string                    │
├───────────────────────────┤
│ a|b|c                     │
│ NULL                      │
│ NULL                      │
│ b                         │
└───────────────────────────┘
See Also

StringValue.join

Source code in ibis/expr/types/arrays.py
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
def join(self, sep: str | ir.StringValue) -> ir.StringValue:
    """Join the elements of this array expression with `sep`.

    Parameters
    ----------
    sep
        Separator to use for joining array elements

    Returns
    -------
    StringValue
        Elements of `self` joined with `sep`

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"arr": [["a", "b", "c"], None, [], ["b", None]]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ arr                  ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<string>        │
    ├──────────────────────┤
    │ ['a', 'b', ... +1]   │
    │ NULL                 │
    │ []                   │
    │ ['b', None]          │
    └──────────────────────┘
    >>> t.arr.join("|")
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayStringJoin('|', arr) ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ string                    │
    ├───────────────────────────┤
    │ a|b|c                     │
    │ NULL                      │
    │ NULL                      │
    │ b                         │
    └───────────────────────────┘

    See Also
    --------
    [`StringValue.join`][ibis.expr.types.strings.StringValue.join]
    """
    return ops.ArrayStringJoin(sep, self).to_expr()

length()

Compute the length of an array.

Returns:

Type Description
IntegerValue

The integer length of each element of self

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"a": [[7, 42], [3], None]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ a                    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [7, 42]              │
│ [3]                  │
│ NULL                 │
└──────────────────────┘
>>> t.a.length()
┏━━━━━━━━━━━━━━━━┓
┃ ArrayLength(a) ┃
┡━━━━━━━━━━━━━━━━┩
│ int64          │
├────────────────┤
│              2 │
│              1 │
│           NULL │
└────────────────┘
Source code in ibis/expr/types/arrays.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def length(self) -> ir.IntegerValue:
    """Compute the length of an array.

    Returns
    -------
    IntegerValue
        The integer length of each element of `self`

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"a": [[7, 42], [3], None]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ a                    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [7, 42]              │
    │ [3]                  │
    │ NULL                 │
    └──────────────────────┘
    >>> t.a.length()
    ┏━━━━━━━━━━━━━━━━┓
    ┃ ArrayLength(a) ┃
    ┡━━━━━━━━━━━━━━━━┩
    │ int64          │
    ├────────────────┤
    │              2 │
    │              1 │
    │           NULL │
    └────────────────┘
    """
    return ops.ArrayLength(self).to_expr()

map(func)

Apply a callable func to each element of this array expression.

Parameters:

Name Type Description Default
func Callable[[ir.Value], ir.Value]

Function to apply to each element of this array

required

Returns:

Type Description
ArrayValue

func applied to every element of this array expression.

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"a": [[1, None, 2], [4], []]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ a                    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [1, None, ... +1]    │
│ [4]                  │
│ []                   │
└──────────────────────┘
>>> t.a.map(lambda x: (x + 100).cast("float"))
┏━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayMap(a)           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━┩
│ array<float64>        │
├───────────────────────┤
│ [101.0, None, ... +1] │
│ [104.0]               │
│ []                    │
└───────────────────────┘
Source code in ibis/expr/types/arrays.py
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
def map(self, func: Callable[[ir.Value], ir.Value]) -> ir.ArrayValue:
    """Apply a callable `func` to each element of this array expression.

    Parameters
    ----------
    func
        Function to apply to each element of this array

    Returns
    -------
    ArrayValue
        `func` applied to every element of this array expression.

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"a": [[1, None, 2], [4], []]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ a                    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [1, None, ... +1]    │
    │ [4]                  │
    │ []                   │
    └──────────────────────┘
    >>> t.a.map(lambda x: (x + 100).cast("float"))
    ┏━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayMap(a)           ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<float64>        │
    ├───────────────────────┤
    │ [101.0, None, ... +1] │
    │ [104.0]               │
    │ []                    │
    └───────────────────────┘
    """
    return ops.ArrayMap(self, func=func).to_expr()

remove(other)

Remove other from self.

Parameters:

Name Type Description Default
other ir.Value

Element to remove from self.

required

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"arr": [[3, 2], [], [42, 2], [2, 2], None]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ arr                  ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [3, 2]               │
│ []                   │
│ [42, 2]              │
│ [2, 2]               │
│ NULL                 │
└──────────────────────┘
>>> t.arr.remove(2)
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayRemove(arr, 2)  ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [3]                  │
│ []                   │
│ [42]                 │
│ []                   │
│ NULL                 │
└──────────────────────┘
Source code in ibis/expr/types/arrays.py
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
def remove(self, other: ir.Value) -> ir.ArrayValue:
    """Remove `other` from `self`.

    Parameters
    ----------
    other
        Element to remove from `self`.

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"arr": [[3, 2], [], [42, 2], [2, 2], None]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ arr                  ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [3, 2]               │
    │ []                   │
    │ [42, 2]              │
    │ [2, 2]               │
    │ NULL                 │
    └──────────────────────┘
    >>> t.arr.remove(2)
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayRemove(arr, 2)  ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [3]                  │
    │ []                   │
    │ [42]                 │
    │ []                   │
    │ NULL                 │
    └──────────────────────┘
    """
    return ops.ArrayRemove(self, other).to_expr()

repeat(n)

Repeat this array n times.

Parameters:

Name Type Description Default
n int | ir.IntegerValue

Number of times to repeat self.

required

Returns:

Type Description
ArrayValue

self repeated n times

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"a": [[7], [3] , None]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ a                    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [7]                  │
│ [3]                  │
│ NULL                 │
└──────────────────────┘
>>> t.a.repeat(2)
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayRepeat(a, 2)    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [7, 7]               │
│ [3, 3]               │
│ []                   │
└──────────────────────┘

repeat is also available using the * operator

>>> 2 * t.a
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayRepeat(a, 2)    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [7, 7]               │
│ [3, 3]               │
│ []                   │
└──────────────────────┘
Source code in ibis/expr/types/arrays.py
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
def repeat(self, n: int | ir.IntegerValue) -> ArrayValue:
    """Repeat this array `n` times.

    Parameters
    ----------
    n
        Number of times to repeat `self`.

    Returns
    -------
    ArrayValue
        `self` repeated `n` times

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"a": [[7], [3] , None]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ a                    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [7]                  │
    │ [3]                  │
    │ NULL                 │
    └──────────────────────┘
    >>> t.a.repeat(2)
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayRepeat(a, 2)    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [7, 7]               │
    │ [3, 3]               │
    │ []                   │
    └──────────────────────┘

    `repeat` is also available using the `*` operator

    >>> 2 * t.a
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayRepeat(a, 2)    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [7, 7]               │
    │ [3, 3]               │
    │ []                   │
    └──────────────────────┘
    """
    return ops.ArrayRepeat(self, n).to_expr()

sort()

Sort the elements in an array.

Returns:

Type Description
ArrayValue

Sorted values in an array

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"arr": [[3, 2], [], [42, 42], None]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ arr                  ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [3, 2]               │
│ []                   │
│ [42, 42]             │
│ NULL                 │
└──────────────────────┘
>>> t.arr.sort()
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArraySort(arr)       ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [2, 3]               │
│ []                   │
│ [42, 42]             │
│ NULL                 │
└──────────────────────┘
Source code in ibis/expr/types/arrays.py
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
def sort(self) -> ir.ArrayValue:
    """Sort the elements in an array.

    Returns
    -------
    ArrayValue
        Sorted values in an array

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"arr": [[3, 2], [], [42, 42], None]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ arr                  ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [3, 2]               │
    │ []                   │
    │ [42, 42]             │
    │ NULL                 │
    └──────────────────────┘
    >>> t.arr.sort()
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArraySort(arr)       ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [2, 3]               │
    │ []                   │
    │ [42, 42]             │
    │ NULL                 │
    └──────────────────────┘
    """
    return ops.ArraySort(self).to_expr()

union(other)

Union two arrays.

Parameters:

Name Type Description Default
other ir.ArrayValue

Another array to union with self

required

Returns:

Type Description
ArrayValue

Unioned arrays

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"arr1": [[3, 2], [], None], "arr2": [[1, 3], [None], [5]]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ arr1                 ┃ arr2                 ┃
┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │ array<int64>         │
├──────────────────────┼──────────────────────┤
│ [3, 2]               │ [1, 3]               │
│ []                   │ [None]               │
│ NULL                 │ [5]                  │
└──────────────────────┴──────────────────────┘
>>> t.arr1.union(t.arr2)
┏━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayUnion(arr1, arr2) ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>           │
├────────────────────────┤
│ [1, 2, ... +1]         │
│ []                     │
│ [5]                    │
└────────────────────────┘
>>> t.arr1.union(t.arr2).contains(3)
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayContains(ArrayUnion(arr1, arr2), 3) ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ boolean                                  │
├──────────────────────────────────────────┤
│ True                                     │
│ False                                    │
│ False                                    │
└──────────────────────────────────────────┘
Source code in ibis/expr/types/arrays.py
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
def union(self, other: ir.ArrayValue) -> ir.ArrayValue:
    """Union two arrays.

    Parameters
    ----------
    other
        Another array to union with `self`

    Returns
    -------
    ArrayValue
        Unioned arrays

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"arr1": [[3, 2], [], None], "arr2": [[1, 3], [None], [5]]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ arr1                 ┃ arr2                 ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │ array<int64>         │
    ├──────────────────────┼──────────────────────┤
    │ [3, 2]               │ [1, 3]               │
    │ []                   │ [None]               │
    │ NULL                 │ [5]                  │
    └──────────────────────┴──────────────────────┘
    >>> t.arr1.union(t.arr2)
    ┏━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayUnion(arr1, arr2) ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>           │
    ├────────────────────────┤
    │ [1, 2, ... +1]         │
    │ []                     │
    │ [5]                    │
    └────────────────────────┘
    >>> t.arr1.union(t.arr2).contains(3)
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayContains(ArrayUnion(arr1, arr2), 3) ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ boolean                                  │
    ├──────────────────────────────────────────┤
    │ True                                     │
    │ False                                    │
    │ False                                    │
    └──────────────────────────────────────────┘
    """
    return ops.ArrayUnion(self, other).to_expr()

unique()

Return the unique values in an array.

Element ordering in array may not be retained.

Returns:

Type Description
ArrayValue

Unique values in an array

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"arr": [[1, 3, 3], [], [42, 42], None]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ arr                  ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [1, 3, ... +1]       │
│ []                   │
│ [42, 42]             │
│ NULL                 │
└──────────────────────┘
>>> t.arr.unique()
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayDistinct(arr)   ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [3, 1]               │
│ []                   │
│ [42]                 │
│ NULL                 │
└──────────────────────┘
Source code in ibis/expr/types/arrays.py
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
def unique(self) -> ir.ArrayValue:
    """Return the unique values in an array.

    !!! note "Element ordering in array may not be retained."

    Returns
    -------
    ArrayValue
        Unique values in an array

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"arr": [[1, 3, 3], [], [42, 42], None]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ arr                  ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [1, 3, ... +1]       │
    │ []                   │
    │ [42, 42]             │
    │ NULL                 │
    └──────────────────────┘
    >>> t.arr.unique()
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayDistinct(arr)   ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [3, 1]               │
    │ []                   │
    │ [42]                 │
    │ NULL                 │
    └──────────────────────┘
    """
    return ops.ArrayDistinct(self).to_expr()

unnest()

Flatten an array into a column.

This operation changes the cardinality of the result

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"a": [[7, 42], [3, 3] , None]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ a                    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │
├──────────────────────┤
│ [7, 42]              │
│ [3, 3]               │
│ NULL                 │
└──────────────────────┘
>>> t.a.unnest()
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     7 │
│    42 │
│     3 │
│     3 │
└───────┘

Returns:

Type Description
ir.Value

Unnested array

Source code in ibis/expr/types/arrays.py
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
def unnest(self) -> ir.Value:
    """Flatten an array into a column.

    !!! note "This operation changes the cardinality of the result"

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"a": [[7, 42], [3, 3] , None]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ a                    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │
    ├──────────────────────┤
    │ [7, 42]              │
    │ [3, 3]               │
    │ NULL                 │
    └──────────────────────┘
    >>> t.a.unnest()
    ┏━━━━━━━┓
    ┃ a     ┃
    ┡━━━━━━━┩
    │ int64 │
    ├───────┤
    │     7 │
    │    42 │
    │     3 │
    │     3 │
    └───────┘

    Returns
    -------
    ir.Value
        Unnested array
    """
    expr = ops.Unnest(self).to_expr()
    try:
        return expr.name(self.get_name())
    except com.ExpressionError:
        return expr

zip(other, *others)

Zip two or more arrays together.

Parameters:

Name Type Description Default
other ir.Array

Another array to zip with self

required
others ir.Array

Additional arrays to zip with self

()

Returns:

Type Description
Array

Array of structs where each struct field is an element of each input array.

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({"numbers": [[3, 2], [], None], "strings": [["a", "c"], None, ["e"]]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ numbers              ┃ strings              ┃
┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│ array<int64>         │ array<string>        │
├──────────────────────┼──────────────────────┤
│ [3, 2]               │ ['a', 'c']           │
│ []                   │ NULL                 │
│ NULL                 │ ['e']                │
└──────────────────────┴──────────────────────┘
>>> expr = t.numbers.zip(t.strings)
>>> expr
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayZip()                           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ array<struct<f1: int64, f2: string>> │
├──────────────────────────────────────┤
│ [{...}, {...}]                       │
│ []                                   │
│ [{...}]                              │
└──────────────────────────────────────┘
>>> expr.unnest()
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ArrayZip()                    ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ struct<f1: int64, f2: string> │
├───────────────────────────────┤
│ {'f1': 3, 'f2': 'a'}          │
│ {'f1': 2, 'f2': 'c'}          │
│ {'f1': None, 'f2': 'e'}       │
└───────────────────────────────┘
Source code in ibis/expr/types/arrays.py
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
def zip(self, other: ir.Array, *others: ir.Array) -> ir.Array:
    """Zip two or more arrays together.

    Parameters
    ----------
    other
        Another array to zip with `self`
    others
        Additional arrays to zip with `self`

    Returns
    -------
    Array
        Array of structs where each struct field is an element of each input
        array.

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({"numbers": [[3, 2], [], None], "strings": [["a", "c"], None, ["e"]]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ numbers              ┃ strings              ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<int64>         │ array<string>        │
    ├──────────────────────┼──────────────────────┤
    │ [3, 2]               │ ['a', 'c']           │
    │ []                   │ NULL                 │
    │ NULL                 │ ['e']                │
    └──────────────────────┴──────────────────────┘
    >>> expr = t.numbers.zip(t.strings)
    >>> expr
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayZip()                           ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<struct<f1: int64, f2: string>> │
    ├──────────────────────────────────────┤
    │ [{...}, {...}]                       │
    │ []                                   │
    │ [{...}]                              │
    └──────────────────────────────────────┘
    >>> expr.unnest()
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ArrayZip()                    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ struct<f1: int64, f2: string> │
    ├───────────────────────────────┤
    │ {'f1': 3, 'f2': 'a'}          │
    │ {'f1': 2, 'f2': 'c'}          │
    │ {'f1': None, 'f2': 'e'}       │
    └───────────────────────────────┘
    """

    return ops.ArrayZip((self, other, *others)).to_expr()

StructValue

Bases: Value

A struct literal or column.

Can be constructed with ibis.struct().

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({'s': [{'a': 1, 'b': 'foo'}, {'a': 3, 'b': None}, None]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ s                           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ struct<a: int64, b: string> │
├─────────────────────────────┤
│ {'a': 1, 'b': 'foo'}        │
│ {'a': 3, 'b': None}         │
│ NULL                        │
└─────────────────────────────┘

Can use either . or [] to access fields:

>>> t.s.a
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     3 │
│  NULL │
└───────┘
>>> t.s['a']
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     3 │
│  NULL │
└───────┘
Source code in ibis/expr/types/structs.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
@public
class StructValue(Value):
    """A struct literal or column.

    Can be constructed with [`ibis.struct()`][ibis.expr.types.struct].

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({'s': [{'a': 1, 'b': 'foo'}, {'a': 3, 'b': None}, None]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ s                           ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ struct<a: int64, b: string> │
    ├─────────────────────────────┤
    │ {'a': 1, 'b': 'foo'}        │
    │ {'a': 3, 'b': None}         │
    │ NULL                        │
    └─────────────────────────────┘

    Can use either `.` or `[]` to access fields:

    >>> t.s.a
    ┏━━━━━━━┓
    ┃ a     ┃
    ┡━━━━━━━┩
    │ int64 │
    ├───────┤
    │     1 │
    │     3 │
    │  NULL │
    └───────┘
    >>> t.s['a']
    ┏━━━━━━━┓
    ┃ a     ┃
    ┡━━━━━━━┩
    │ int64 │
    ├───────┤
    │     1 │
    │     3 │
    │  NULL │
    └───────┘
    """

    def __dir__(self):
        out = set(dir(type(self)))
        out.update(
            c for c in self.type().names if c.isidentifier() and not iskeyword(c)
        )
        return sorted(out)

    def _ipython_key_completions_(self) -> list[str]:
        return sorted(self.type().names)

    def __getitem__(self, name: str) -> ir.Value:
        """Extract the `name` field from this struct.

        Parameters
        ----------
        name
            The name of the field to access.

        Returns
        -------
        Value
            An expression with the type of the field being accessed.

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({'s': [{'a': 1, 'b': 'foo'}, {'a': 3, 'b': None}, None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ s                           ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ struct<a: int64, b: string> │
        ├─────────────────────────────┤
        │ {'a': 1, 'b': 'foo'}        │
        │ {'a': 3, 'b': None}         │
        │ NULL                        │
        └─────────────────────────────┘
        >>> t.s['a']
        ┏━━━━━━━┓
        ┃ a     ┃
        ┡━━━━━━━┩
        │ int64 │
        ├───────┤
        │     1 │
        │     3 │
        │  NULL │
        └───────┘
        >>> t.s['b']
        ┏━━━━━━━━┓
        ┃ b      ┃
        ┡━━━━━━━━┩
        │ string │
        ├────────┤
        │ foo    │
        │ NULL   │
        │ NULL   │
        └────────┘
        >>> t.s['foo_bar']
        Traceback (most recent call last):
            ...
        KeyError: 'foo_bar'
        """
        if name not in self.names:
            raise KeyError(name)
        return ops.StructField(self, name).to_expr()

    def __setstate__(self, instance_dictionary):
        self.__dict__ = instance_dictionary

    def __getattr__(self, name: str) -> ir.Value:
        """Extract the `name` field from this struct.

        Parameters
        ----------
        name
            The name of the field to access.

        Returns
        -------
        Value
            An expression with the type of the field being accessed.

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({'s': [{'a': 1, 'b': 'foo'}, {'a': 3, 'b': None}, None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ s                           ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ struct<a: int64, b: string> │
        ├─────────────────────────────┤
        │ {'a': 1, 'b': 'foo'}        │
        │ {'a': 3, 'b': None}         │
        │ NULL                        │
        └─────────────────────────────┘
        >>> t.s.a
        ┏━━━━━━━┓
        ┃ a     ┃
        ┡━━━━━━━┩
        │ int64 │
        ├───────┤
        │     1 │
        │     3 │
        │  NULL │
        └───────┘
        >>> t.s.b
        ┏━━━━━━━━┓
        ┃ b      ┃
        ┡━━━━━━━━┩
        │ string │
        ├────────┤
        │ foo    │
        │ NULL   │
        │ NULL   │
        └────────┘
        >>> t.s.foo_bar
        Traceback (most recent call last):
            ...
        AttributeError: foo_bar
        """
        try:
            return self[name]
        except KeyError:
            raise AttributeError(name) from None

    @property
    def names(self) -> Sequence[str]:
        """Return the field names of the struct."""
        return self.type().names

    @property
    def types(self) -> Sequence[dt.DataType]:
        """Return the field types of the struct."""
        return self.type().types

    @property
    def fields(self) -> Mapping[str, dt.DataType]:
        """Return a mapping from field name to field type of the struct."""
        return self.type().fields

    def lift(self) -> ir.Table:
        """Project the fields of `self` into a table.

        This method is useful when analyzing data that has deeply nested
        structs or arrays of structs. `lift` can be chained to avoid repeating
        column names and table references.

        Returns
        -------
        Table
            A projection with this struct expression's fields.

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable(
        ...     {
        ...         "pos": [
        ...             {"lat": 10.1, "lon": 30.3},
        ...             {"lat": 10.2, "lon": 30.2},
        ...             {"lat": 10.3, "lon": 30.1},
        ...         ]
        ...     }
        ... )
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ pos                                ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ struct<lat: float64, lon: float64> │
        ├────────────────────────────────────┤
        │ {'lat': 10.1, 'lon': 30.3}         │
        │ {'lat': 10.2, 'lon': 30.2}         │
        │ {'lat': 10.3, 'lon': 30.1}         │
        └────────────────────────────────────┘
        >>> t.pos.lift()
        ┏━━━━━━━━━┳━━━━━━━━━┓
        ┃ lat     ┃ lon     ┃
        ┡━━━━━━━━━╇━━━━━━━━━┩
        │ float64 │ float64 │
        ├─────────┼─────────┤
        │    10.1 │    30.3 │
        │    10.2 │    30.2 │
        │    10.3 │    30.1 │
        └─────────┴─────────┘

        See Also
        --------
        [`Table.unpack`][ibis.expr.types.relations.Table.unpack].
        """
        import ibis.expr.analysis as an

        # TODO(kszucs): avoid expression roundtripping
        table = an.find_first_base_table(self.op()).to_expr()
        return table[[self[name] for name in self.names]]

    def destructure(self) -> list[ir.ValueExpr]:
        """Destructure a ``StructValue`` into the corresponding struct fields.

        When assigned, a destruct value will be destructured and assigned to
        multiple columns.

        Returns
        -------
        list[AnyValue]
            Value expressions corresponding to the struct fields.

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> t = ibis.memtable({'s': [{'a': 1, 'b': 'foo'}, {'a': 3, 'b': None}, None]})
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ s                           ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
        │ struct<a: int64, b: string> │
        ├─────────────────────────────┤
        │ {'a': 1, 'b': 'foo'}        │
        │ {'a': 3, 'b': None}         │
        │ NULL                        │
        └─────────────────────────────┘
        >>> a, b = t.s.destructure()
        >>> a
        ┏━━━━━━━┓
        ┃ a     ┃
        ┡━━━━━━━┩
        │ int64 │
        ├───────┤
        │     1 │
        │     3 │
        │  NULL │
        └───────┘
        >>> b
        ┏━━━━━━━━┓
        ┃ b      ┃
        ┡━━━━━━━━┩
        │ string │
        ├────────┤
        │ foo    │
        │ NULL   │
        │ NULL   │
        └────────┘
        """
        return [self[field_name] for field_name in self.type().names]

Attributes

fields: Mapping[str, dt.DataType] property

Return a mapping from field name to field type of the struct.

names: Sequence[str] property

Return the field names of the struct.

types: Sequence[dt.DataType] property

Return the field types of the struct.

Functions

destructure()

Destructure a StructValue into the corresponding struct fields.

When assigned, a destruct value will be destructured and assigned to multiple columns.

Returns:

Type Description
list[AnyValue]

Value expressions corresponding to the struct fields.

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable({'s': [{'a': 1, 'b': 'foo'}, {'a': 3, 'b': None}, None]})
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ s                           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ struct<a: int64, b: string> │
├─────────────────────────────┤
│ {'a': 1, 'b': 'foo'}        │
│ {'a': 3, 'b': None}         │
│ NULL                        │
└─────────────────────────────┘
>>> a, b = t.s.destructure()
>>> a
┏━━━━━━━┓
┃ a     ┃
┡━━━━━━━┩
│ int64 │
├───────┤
│     1 │
│     3 │
│  NULL │
└───────┘
>>> b
┏━━━━━━━━┓
┃ b      ┃
┡━━━━━━━━┩
│ string │
├────────┤
│ foo    │
│ NULL   │
│ NULL   │
└────────┘
Source code in ibis/expr/types/structs.py
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
def destructure(self) -> list[ir.ValueExpr]:
    """Destructure a ``StructValue`` into the corresponding struct fields.

    When assigned, a destruct value will be destructured and assigned to
    multiple columns.

    Returns
    -------
    list[AnyValue]
        Value expressions corresponding to the struct fields.

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable({'s': [{'a': 1, 'b': 'foo'}, {'a': 3, 'b': None}, None]})
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ s                           ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ struct<a: int64, b: string> │
    ├─────────────────────────────┤
    │ {'a': 1, 'b': 'foo'}        │
    │ {'a': 3, 'b': None}         │
    │ NULL                        │
    └─────────────────────────────┘
    >>> a, b = t.s.destructure()
    >>> a
    ┏━━━━━━━┓
    ┃ a     ┃
    ┡━━━━━━━┩
    │ int64 │
    ├───────┤
    │     1 │
    │     3 │
    │  NULL │
    └───────┘
    >>> b
    ┏━━━━━━━━┓
    ┃ b      ┃
    ┡━━━━━━━━┩
    │ string │
    ├────────┤
    │ foo    │
    │ NULL   │
    │ NULL   │
    └────────┘
    """
    return [self[field_name] for field_name in self.type().names]

lift()

Project the fields of self into a table.

This method is useful when analyzing data that has deeply nested structs or arrays of structs. lift can be chained to avoid repeating column names and table references.

Returns:

Type Description
Table

A projection with this struct expression's fields.

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.memtable(
...     {
...         "pos": [
...             {"lat": 10.1, "lon": 30.3},
...             {"lat": 10.2, "lon": 30.2},
...             {"lat": 10.3, "lon": 30.1},
...         ]
...     }
... )
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ pos                                ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ struct<lat: float64, lon: float64> │
├────────────────────────────────────┤
│ {'lat': 10.1, 'lon': 30.3}         │
│ {'lat': 10.2, 'lon': 30.2}         │
│ {'lat': 10.3, 'lon': 30.1}         │
└────────────────────────────────────┘
>>> t.pos.lift()
┏━━━━━━━━━┳━━━━━━━━━┓
┃ lat     ┃ lon     ┃
┡━━━━━━━━━╇━━━━━━━━━┩
│ float64 │ float64 │
├─────────┼─────────┤
│    10.1 │    30.3 │
│    10.2 │    30.2 │
│    10.3 │    30.1 │
└─────────┴─────────┘
See Also

Table.unpack.

Source code in ibis/expr/types/structs.py
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
def lift(self) -> ir.Table:
    """Project the fields of `self` into a table.

    This method is useful when analyzing data that has deeply nested
    structs or arrays of structs. `lift` can be chained to avoid repeating
    column names and table references.

    Returns
    -------
    Table
        A projection with this struct expression's fields.

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> t = ibis.memtable(
    ...     {
    ...         "pos": [
    ...             {"lat": 10.1, "lon": 30.3},
    ...             {"lat": 10.2, "lon": 30.2},
    ...             {"lat": 10.3, "lon": 30.1},
    ...         ]
    ...     }
    ... )
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ pos                                ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ struct<lat: float64, lon: float64> │
    ├────────────────────────────────────┤
    │ {'lat': 10.1, 'lon': 30.3}         │
    │ {'lat': 10.2, 'lon': 30.2}         │
    │ {'lat': 10.3, 'lon': 30.1}         │
    └────────────────────────────────────┘
    >>> t.pos.lift()
    ┏━━━━━━━━━┳━━━━━━━━━┓
    ┃ lat     ┃ lon     ┃
    ┡━━━━━━━━━╇━━━━━━━━━┩
    │ float64 │ float64 │
    ├─────────┼─────────┤
    │    10.1 │    30.3 │
    │    10.2 │    30.2 │
    │    10.3 │    30.1 │
    └─────────┴─────────┘

    See Also
    --------
    [`Table.unpack`][ibis.expr.types.relations.Table.unpack].
    """
    import ibis.expr.analysis as an

    # TODO(kszucs): avoid expression roundtripping
    table = an.find_first_base_table(self.op()).to_expr()
    return table[[self[name] for name in self.names]]

MapValue

Bases: Value

A map literal or column expression.

Can be constructed with ibis.map().

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> import pyarrow as pa
>>> tab = pa.table({
...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
...                  type=pa.map_(pa.utf8(), pa.int64()))})
>>> t = ibis.memtable(tab)
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ m                    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ map<!string, int64>  │
├──────────────────────┤
│ {'a': 1, 'b': 2}     │
│ {'a': 1}             │
│ NULL                 │
└──────────────────────┘

Can use [] to access values:

>>> t.m['a']
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ MapGet(m, 'a', None) ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ int64                │
├──────────────────────┤
│                    1 │
│                    1 │
│                 NULL │
└──────────────────────┘

To provide default values, use get:

>>> t.m.get('b', 0)
┏━━━━━━━━━━━━━━━━━━━┓
┃ MapGet(m, 'b', 0) ┃
┡━━━━━━━━━━━━━━━━━━━┩
│ int64             │
├───────────────────┤
│                 2 │
│                 0 │
│                 0 │
└───────────────────┘
Source code in ibis/expr/types/maps.py
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
@public
class MapValue(Value):
    """A map literal or column expression.

    Can be constructed with [`ibis.map()`][ibis.expr.types.map].

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> import pyarrow as pa
    >>> tab = pa.table({
    ...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
    ...                  type=pa.map_(pa.utf8(), pa.int64()))})
    >>> t = ibis.memtable(tab)
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ m                    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ map<!string, int64>  │
    ├──────────────────────┤
    │ {'a': 1, 'b': 2}     │
    │ {'a': 1}             │
    │ NULL                 │
    └──────────────────────┘

    Can use `[]` to access values:
    >>> t.m['a']
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ MapGet(m, 'a', None) ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ int64                │
    ├──────────────────────┤
    │                    1 │
    │                    1 │
    │                 NULL │
    └──────────────────────┘

    To provide default values, use `get`:
    >>> t.m.get('b', 0)
    ┏━━━━━━━━━━━━━━━━━━━┓
    ┃ MapGet(m, 'b', 0) ┃
    ┡━━━━━━━━━━━━━━━━━━━┩
    │ int64             │
    ├───────────────────┤
    │                 2 │
    │                 0 │
    │                 0 │
    └───────────────────┘
    """

    def get(
        self,
        key: ir.Value,
        default: ir.Value | None = None,
    ) -> ir.Value:
        """Return the value for `key` from `expr`.

        Return `default` if `key` is not in the map.

        Parameters
        ----------
        key
            Expression to use for key
        default
            Expression to return if `key` is not a key in `expr`

        Returns
        -------
        Value
            The element type of `self`

        Examples
        --------
        >>> import ibis
        >>> import pyarrow as pa
        >>> ibis.options.interactive = True
        >>> tab = pa.table({
        ...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
        ...                  type=pa.map_(pa.utf8(), pa.int64()))})
        >>> t = ibis.memtable(tab)
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ m                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ map<!string, int64>  │
        ├──────────────────────┤
        │ {'a': 1, 'b': 2}     │
        │ {'a': 1}             │
        │ NULL                 │
        └──────────────────────┘
        >>> t.m.get("a")
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ MapGet(m, 'a', None) ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ int64                │
        ├──────────────────────┤
        │                    1 │
        │                    1 │
        │                 NULL │
        └──────────────────────┘
        >>> t.m.get("b")
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ MapGet(m, 'b', None) ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ int64                │
        ├──────────────────────┤
        │                    2 │
        │                 NULL │
        │                 NULL │
        └──────────────────────┘
        >>> t.m.get("b", 0)
        ┏━━━━━━━━━━━━━━━━━━━┓
        ┃ MapGet(m, 'b', 0) ┃
        ┡━━━━━━━━━━━━━━━━━━━┩
        │ int64             │
        ├───────────────────┤
        │                 2 │
        │                 0 │
        │                 0 │
        └───────────────────┘
        """

        return ops.MapGet(self, key, default).to_expr()

    def length(self) -> ir.IntegerValue:
        """Return the number of key-value pairs in the map.

        Returns
        -------
        IntegerValue
            The number of elements in `self`

        Examples
        --------
        >>> import ibis
        >>> import pyarrow as pa
        >>> ibis.options.interactive = True
        >>> tab = pa.table({
        ...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
        ...                  type=pa.map_(pa.utf8(), pa.int64()))})
        >>> t = ibis.memtable(tab)
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ m                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ map<!string, int64>  │
        ├──────────────────────┤
        │ {'a': 1, 'b': 2}     │
        │ {'a': 1}             │
        │ NULL                 │
        └──────────────────────┘
        >>> t.m.length()
        ┏━━━━━━━━━━━━━━┓
        ┃ MapLength(m) ┃
        ┡━━━━━━━━━━━━━━┩
        │ int64        │
        ├──────────────┤
        │            2 │
        │            1 │
        │         NULL │
        └──────────────┘
        """
        return ops.MapLength(self).to_expr()

    def __getitem__(self, key: ir.Value) -> ir.Value:
        """Get the value for a given map `key`.

        !!! info "This operation may have different semantics depending on the backend."

            Some backends return `NULL` when a key is missing, others may fail
            the query.

        Parameters
        ----------
        key
            A map key

        Returns
        -------
        Value
            An element with the value type of the map

        Examples
        --------
        >>> import ibis
        >>> import pyarrow as pa
        >>> ibis.options.interactive = True
        >>> tab = pa.table({
        ...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
        ...                  type=pa.map_(pa.utf8(), pa.int64()))})
        >>> t = ibis.memtable(tab)
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ m                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ map<!string, int64>  │
        ├──────────────────────┤
        │ {'a': 1, 'b': 2}     │
        │ {'a': 1}             │
        │ NULL                 │
        └──────────────────────┘
        >>> t.m["a"]
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ MapGet(m, 'a', None) ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ int64                │
        ├──────────────────────┤
        │                    1 │
        │                    1 │
        │                 NULL │
        └──────────────────────┘
        """
        return ops.MapGet(self, key).to_expr()

    def contains(
        self, key: int | str | ir.IntegerValue | ir.StringValue
    ) -> ir.BooleanValue:
        """Return whether the map contains `key`.

        Parameters
        ----------
        key
            Mapping key for which to check

        Returns
        -------
        BooleanValue
            Boolean indicating the presence of `key` in the map expression

        Examples
        --------
        >>> import ibis
        >>> import pyarrow as pa
        >>> ibis.options.interactive = True
        >>> tab = pa.table({
        ...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
        ...                  type=pa.map_(pa.utf8(), pa.int64()))})
        >>> t = ibis.memtable(tab)
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ m                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ map<!string, int64>   │
        ├──────────────────────┤
        │ {'a': 1, 'b': 2}     │
        │ {'a': 1}             │
        │ NULL                 │
        └──────────────────────┘
        >>> t.m.contains("b")
        ┏━━━━━━━━━━━━━━━━━━━━━┓
        ┃ MapContains(m, 'b') ┃
        ┡━━━━━━━━━━━━━━━━━━━━━┩
        │ boolean             │
        ├─────────────────────┤
        │ True                │
        │ False               │
        │ False               │
        └─────────────────────┘
        """
        return ops.MapContains(self, key).to_expr()

    def keys(self) -> ir.ArrayValue:
        """Extract the keys of a map.

        Returns
        -------
        ArrayValue
            The keys of `self`

        Examples
        --------
        >>> import ibis
        >>> import pyarrow as pa
        >>> ibis.options.interactive = True
        >>> tab = pa.table({
        ...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
        ...                  type=pa.map_(pa.utf8(), pa.int64()))})
        >>> t = ibis.memtable(tab)
        >>> t
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ m                    ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ map<!string, int64>  │
        ├──────────────────────┤
        │ {'a': 1, 'b': 2}     │
        │ {'a': 1}             │
        │ NULL                 │
        └──────────────────────┘
        >>> t.m.keys()
        ┏━━━━━━━━━━━━━━━━━━━━━━┓
        ┃ MapKeys(m)           ┃
        ┡━━━━━━━━━━━━━━━━━━━━━━┩
        │ array<!string>       │
        ├──────────────────────┤
        │ ['a', 'b']           │
        │ ['a']                │
        │ NULL                 │
        └──────────────────────┘
        """
        return ops.MapKeys(self).to_expr()

    def values(self) -> ir.ArrayValue:
        """Extract the values of a map.

        Returns
        -------
        ArrayValue
            The values of `self`

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> m = ibis.map({"a": 1, "b": 2})
        >>> m.values()
        [1, 2]
        """
        return ops.MapValues(self).to_expr()

    def __add__(self, other: MapValue) -> MapValue:
        """Concatenate this map with another.

        Parameters
        ----------
        other
            Map to concatenate with `self`

        Returns
        -------
        MapValue
            `self` concatenated with `other`

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> m1 = ibis.map({"a": 1, "b": 2})
        >>> m2 = ibis.map({"c": 3, "d": 4})
        >>> m1 + m2
        {'a': 1, 'b': 2, 'c': 3, 'd': 4}
        """
        return ops.MapMerge(self, other).to_expr()

    def __radd__(self, other: MapValue) -> MapValue:
        """Concatenate this map with another.

        Parameters
        ----------
        other
            Map to concatenate with `self`

        Returns
        -------
        MapValue
            `self` concatenated with `other`

        Examples
        --------
        >>> import ibis
        >>> ibis.options.interactive = True
        >>> m1 = ibis.map({"a": 1, "b": 2})
        >>> m2 = ibis.map({"c": 3, "d": 4})
        >>> m1 + m2
        {'a': 1, 'b': 2, 'c': 3, 'd': 4}
        """
        return ops.MapMerge(self, other).to_expr()

Functions

contains(key)

Return whether the map contains key.

Parameters:

Name Type Description Default
key int | str | ir.IntegerValue | ir.StringValue

Mapping key for which to check

required

Returns:

Type Description
BooleanValue

Boolean indicating the presence of key in the map expression

Examples:

>>> import ibis
>>> import pyarrow as pa
>>> ibis.options.interactive = True
>>> tab = pa.table({
...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
...                  type=pa.map_(pa.utf8(), pa.int64()))})
>>> t = ibis.memtable(tab)
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ m                    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ map<!string, int64>   │
├──────────────────────┤
│ {'a': 1, 'b': 2}     │
│ {'a': 1}             │
│ NULL                 │
└──────────────────────┘
>>> t.m.contains("b")
┏━━━━━━━━━━━━━━━━━━━━━┓
┃ MapContains(m, 'b') ┃
┡━━━━━━━━━━━━━━━━━━━━━┩
│ boolean             │
├─────────────────────┤
│ True                │
│ False               │
│ False               │
└─────────────────────┘
Source code in ibis/expr/types/maps.py
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
def contains(
    self, key: int | str | ir.IntegerValue | ir.StringValue
) -> ir.BooleanValue:
    """Return whether the map contains `key`.

    Parameters
    ----------
    key
        Mapping key for which to check

    Returns
    -------
    BooleanValue
        Boolean indicating the presence of `key` in the map expression

    Examples
    --------
    >>> import ibis
    >>> import pyarrow as pa
    >>> ibis.options.interactive = True
    >>> tab = pa.table({
    ...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
    ...                  type=pa.map_(pa.utf8(), pa.int64()))})
    >>> t = ibis.memtable(tab)
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ m                    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ map<!string, int64>   │
    ├──────────────────────┤
    │ {'a': 1, 'b': 2}     │
    │ {'a': 1}             │
    │ NULL                 │
    └──────────────────────┘
    >>> t.m.contains("b")
    ┏━━━━━━━━━━━━━━━━━━━━━┓
    ┃ MapContains(m, 'b') ┃
    ┡━━━━━━━━━━━━━━━━━━━━━┩
    │ boolean             │
    ├─────────────────────┤
    │ True                │
    │ False               │
    │ False               │
    └─────────────────────┘
    """
    return ops.MapContains(self, key).to_expr()

get(key, default=None)

Return the value for key from expr.

Return default if key is not in the map.

Parameters:

Name Type Description Default
key ir.Value

Expression to use for key

required
default ir.Value | None

Expression to return if key is not a key in expr

None

Returns:

Type Description
Value

The element type of self

Examples:

>>> import ibis
>>> import pyarrow as pa
>>> ibis.options.interactive = True
>>> tab = pa.table({
...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
...                  type=pa.map_(pa.utf8(), pa.int64()))})
>>> t = ibis.memtable(tab)
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ m                    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ map<!string, int64>  │
├──────────────────────┤
│ {'a': 1, 'b': 2}     │
│ {'a': 1}             │
│ NULL                 │
└──────────────────────┘
>>> t.m.get("a")
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ MapGet(m, 'a', None) ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ int64                │
├──────────────────────┤
│                    1 │
│                    1 │
│                 NULL │
└──────────────────────┘
>>> t.m.get("b")
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ MapGet(m, 'b', None) ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ int64                │
├──────────────────────┤
│                    2 │
│                 NULL │
│                 NULL │
└──────────────────────┘
>>> t.m.get("b", 0)
┏━━━━━━━━━━━━━━━━━━━┓
┃ MapGet(m, 'b', 0) ┃
┡━━━━━━━━━━━━━━━━━━━┩
│ int64             │
├───────────────────┤
│                 2 │
│                 0 │
│                 0 │
└───────────────────┘
Source code in ibis/expr/types/maps.py
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
def get(
    self,
    key: ir.Value,
    default: ir.Value | None = None,
) -> ir.Value:
    """Return the value for `key` from `expr`.

    Return `default` if `key` is not in the map.

    Parameters
    ----------
    key
        Expression to use for key
    default
        Expression to return if `key` is not a key in `expr`

    Returns
    -------
    Value
        The element type of `self`

    Examples
    --------
    >>> import ibis
    >>> import pyarrow as pa
    >>> ibis.options.interactive = True
    >>> tab = pa.table({
    ...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
    ...                  type=pa.map_(pa.utf8(), pa.int64()))})
    >>> t = ibis.memtable(tab)
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ m                    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ map<!string, int64>  │
    ├──────────────────────┤
    │ {'a': 1, 'b': 2}     │
    │ {'a': 1}             │
    │ NULL                 │
    └──────────────────────┘
    >>> t.m.get("a")
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ MapGet(m, 'a', None) ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ int64                │
    ├──────────────────────┤
    │                    1 │
    │                    1 │
    │                 NULL │
    └──────────────────────┘
    >>> t.m.get("b")
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ MapGet(m, 'b', None) ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ int64                │
    ├──────────────────────┤
    │                    2 │
    │                 NULL │
    │                 NULL │
    └──────────────────────┘
    >>> t.m.get("b", 0)
    ┏━━━━━━━━━━━━━━━━━━━┓
    ┃ MapGet(m, 'b', 0) ┃
    ┡━━━━━━━━━━━━━━━━━━━┩
    │ int64             │
    ├───────────────────┤
    │                 2 │
    │                 0 │
    │                 0 │
    └───────────────────┘
    """

    return ops.MapGet(self, key, default).to_expr()

keys()

Extract the keys of a map.

Returns:

Type Description
ArrayValue

The keys of self

Examples:

>>> import ibis
>>> import pyarrow as pa
>>> ibis.options.interactive = True
>>> tab = pa.table({
...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
...                  type=pa.map_(pa.utf8(), pa.int64()))})
>>> t = ibis.memtable(tab)
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ m                    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ map<!string, int64>  │
├──────────────────────┤
│ {'a': 1, 'b': 2}     │
│ {'a': 1}             │
│ NULL                 │
└──────────────────────┘
>>> t.m.keys()
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ MapKeys(m)           ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ array<!string>       │
├──────────────────────┤
│ ['a', 'b']           │
│ ['a']                │
│ NULL                 │
└──────────────────────┘
Source code in ibis/expr/types/maps.py
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
def keys(self) -> ir.ArrayValue:
    """Extract the keys of a map.

    Returns
    -------
    ArrayValue
        The keys of `self`

    Examples
    --------
    >>> import ibis
    >>> import pyarrow as pa
    >>> ibis.options.interactive = True
    >>> tab = pa.table({
    ...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
    ...                  type=pa.map_(pa.utf8(), pa.int64()))})
    >>> t = ibis.memtable(tab)
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ m                    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ map<!string, int64>  │
    ├──────────────────────┤
    │ {'a': 1, 'b': 2}     │
    │ {'a': 1}             │
    │ NULL                 │
    └──────────────────────┘
    >>> t.m.keys()
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ MapKeys(m)           ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ array<!string>       │
    ├──────────────────────┤
    │ ['a', 'b']           │
    │ ['a']                │
    │ NULL                 │
    └──────────────────────┘
    """
    return ops.MapKeys(self).to_expr()

length()

Return the number of key-value pairs in the map.

Returns:

Type Description
IntegerValue

The number of elements in self

Examples:

>>> import ibis
>>> import pyarrow as pa
>>> ibis.options.interactive = True
>>> tab = pa.table({
...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
...                  type=pa.map_(pa.utf8(), pa.int64()))})
>>> t = ibis.memtable(tab)
>>> t
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ m                    ┃
┡━━━━━━━━━━━━━━━━━━━━━━┩
│ map<!string, int64>  │
├──────────────────────┤
│ {'a': 1, 'b': 2}     │
│ {'a': 1}             │
│ NULL                 │
└──────────────────────┘
>>> t.m.length()
┏━━━━━━━━━━━━━━┓
┃ MapLength(m) ┃
┡━━━━━━━━━━━━━━┩
│ int64        │
├──────────────┤
│            2 │
│            1 │
│         NULL │
└──────────────┘
Source code in ibis/expr/types/maps.py
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
def length(self) -> ir.IntegerValue:
    """Return the number of key-value pairs in the map.

    Returns
    -------
    IntegerValue
        The number of elements in `self`

    Examples
    --------
    >>> import ibis
    >>> import pyarrow as pa
    >>> ibis.options.interactive = True
    >>> tab = pa.table({
    ...    "m": pa.array([[("a", 1), ("b", 2)], [("a", 1)], None],
    ...                  type=pa.map_(pa.utf8(), pa.int64()))})
    >>> t = ibis.memtable(tab)
    >>> t
    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ m                    ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━┩
    │ map<!string, int64>  │
    ├──────────────────────┤
    │ {'a': 1, 'b': 2}     │
    │ {'a': 1}             │
    │ NULL                 │
    └──────────────────────┘
    >>> t.m.length()
    ┏━━━━━━━━━━━━━━┓
    ┃ MapLength(m) ┃
    ┡━━━━━━━━━━━━━━┩
    │ int64        │
    ├──────────────┤
    │            2 │
    │            1 │
    │         NULL │
    └──────────────┘
    """
    return ops.MapLength(self).to_expr()

values()

Extract the values of a map.

Returns:

Type Description
ArrayValue

The values of self

Examples:

>>> import ibis
>>> ibis.options.interactive = True
>>> m = ibis.map({"a": 1, "b": 2})
>>> m.values()
[1, 2]
Source code in ibis/expr/types/maps.py
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
def values(self) -> ir.ArrayValue:
    """Extract the values of a map.

    Returns
    -------
    ArrayValue
        The values of `self`

    Examples
    --------
    >>> import ibis
    >>> ibis.options.interactive = True
    >>> m = ibis.map({"a": 1, "b": 2})
    >>> m.values()
    [1, 2]
    """
    return ops.MapValues(self).to_expr()

Last update: June 22, 2023