Skip to content

TaggedTable

Bases: Table

A tagged table is a table that additionally knows which columns are features and which are the target to predict.

Parameters:

Name Type Description Default
data Mapping[str, Sequence[Any]]

The data.

required
target_name str

Name of the target column.

required
feature_names list[str] | None

Names of the feature columns. If None, all columns except the target column are used.

None

Raises:

Type Description
ColumnLengthMismatchError

If columns have different lengths.

ValueError

If the target column is also a feature column.

ValueError

If no feature columns are specified.

Examples:

>>> from safeds.data.tabular.containers import Table, TaggedTable
>>> table = Table({"col1": ["a", "b"], "col2": [1, 2]})
>>> tagged_table = table.tag_columns("col2", ["col1"])
Source code in src/safeds/data/tabular/containers/_tagged_table.py
 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
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
class TaggedTable(Table):
    """
    A tagged table is a table that additionally knows which columns are features and which are the target to predict.

    Parameters
    ----------
    data : Mapping[str, Sequence[Any]]
        The data.
    target_name : str
        Name of the target column.
    feature_names : list[str] | None
        Names of the feature columns. If None, all columns except the target column are used.

    Raises
    ------
    ColumnLengthMismatchError
        If columns have different lengths.
    ValueError
        If the target column is also a feature column.
    ValueError
        If no feature columns are specified.

    Examples
    --------
    >>> from safeds.data.tabular.containers import Table, TaggedTable
    >>> table = Table({"col1": ["a", "b"], "col2": [1, 2]})
    >>> tagged_table = table.tag_columns("col2", ["col1"])
    """

    # ------------------------------------------------------------------------------------------------------------------
    # Creation
    # ------------------------------------------------------------------------------------------------------------------

    @staticmethod
    def _from_table(
        table: Table,
        target_name: str,
        feature_names: list[str] | None = None,
    ) -> TaggedTable:
        """
        Create a tagged table from a table.

        Parameters
        ----------
        table : Table
            The table.
        target_name : str
            Name of the target column.
        feature_names : list[str] | None
            Names of the feature columns. If None, all columns except the target column are used.

        Returns
        -------
        tagged_table : TaggedTable
            The created table.

        Raises
        ------
        UnknownColumnNameError
            If target_name matches none of the column names.
        ValueError
            If the target column is also a feature column.
        ValueError
            If no feature columns are specified.

        Examples
        --------
        >>> from safeds.data.tabular.containers import Table, TaggedTable
        >>> table = Table({"col1": ["a", "b", "c", "a"], "col2": [1, 2, 3, 4]})
        >>> tagged_table = TaggedTable._from_table(table, "col2", ["col1"])
        """
        table = table._as_table()
        if target_name not in table.column_names:
            raise UnknownColumnNameError([target_name])

        # If no feature names are specified, use all columns except the target column
        if feature_names is None:
            feature_names = table.column_names
            feature_names.remove(target_name)

        # Validate inputs
        if target_name in feature_names:
            raise ValueError(f"Column '{target_name}' cannot be both feature and target.")
        if len(feature_names) == 0:
            raise ValueError("At least one feature column must be specified.")

        # Create result
        result = object.__new__(TaggedTable)

        result._data = table._data
        result._schema = table.schema
        result._features = table.keep_only_columns(feature_names)
        result._target = table.get_column(target_name)

        return result

    # ------------------------------------------------------------------------------------------------------------------
    # Dunder methods
    # ------------------------------------------------------------------------------------------------------------------

    def __init__(
        self,
        data: Mapping[str, Sequence[Any]],
        target_name: str,
        feature_names: list[str] | None = None,
    ):
        """
        Create a tagged table from a mapping of column names to their values.

        Parameters
        ----------
        data : Mapping[str, Sequence[Any]]
            The data.
        target_name : str
            Name of the target column.
        feature_names : list[str] | None
            Names of the feature columns. If None, all columns except the target column are used.

        Raises
        ------
        ColumnLengthMismatchError
            If columns have different lengths.
        ValueError
            If the target column is also a feature column.
        ValueError
            If no feature columns are specified.

        Examples
        --------
        >>> from safeds.data.tabular.containers import TaggedTable
        >>> table = TaggedTable({"a": [1, 2, 3], "b": [4, 5, 6]}, "b", ["a"])
        """
        super().__init__(data)
        _data = Table(data)

        # If no feature names are specified, use all columns except the target column
        if feature_names is None:
            feature_names = _data.column_names
            if target_name in feature_names:
                feature_names.remove(target_name)

        # Validate inputs
        if target_name in feature_names:
            raise ValueError(f"Column '{target_name}' cannot be both feature and target.")
        if len(feature_names) == 0:
            raise ValueError("At least one feature column must be specified.")

        self._features: Table = _data.keep_only_columns(feature_names)
        self._target: Column = _data.get_column(target_name)

    def __eq__(self, other: object) -> bool:
        """
        Compare two tagged table instances.

        Returns
        -------
        'True' if contents and tags are equal, 'False' otherwise.
        """
        if not isinstance(other, TaggedTable):
            return NotImplemented
        if self is other:
            return True
        return self.target == other.target and self.features == other.features and Table.__eq__(self, other)

    def __hash__(self) -> int:
        """
        Return a deterministic hash value for this tagged table.

        Returns
        -------
        hash:
            The hash value.
        """
        return _structural_hash(self.target, self.features, Table.__hash__(self))

    def __sizeof__(self) -> int:
        """
        Return the complete size of this object.

        Returns
        -------
        size:
            Size of this object in bytes.
        """
        return Table.__sizeof__(self) + sys.getsizeof(self._features) + sys.getsizeof(self._target)

    # ------------------------------------------------------------------------------------------------------------------
    # Properties
    # ------------------------------------------------------------------------------------------------------------------

    @property
    def features(self) -> Table:
        """
        Get the feature columns of the tagged table.

        Returns
        -------
        Table
            The table containing the feature columns.
        """
        return self._features

    @property
    def target(self) -> Column:
        """
        Get the target column of the tagged table.

        Returns
        -------
        Column
            The target column.
        """
        return self._target

    # ------------------------------------------------------------------------------------------------------------------
    # Specific methods from TaggedTable class:
    # ------------------------------------------------------------------------------------------------------------------

    def add_column_as_feature(self, column: Column) -> TaggedTable:
        """
        Return a new table with the provided column attached at the end, as a feature column.

        the original table is not modified.

        Parameters
        ----------
        column : Column
            The column to be added.

        Returns
        -------
        result : TaggedTable
            The table with the attached feature column.

        Raises
        ------
        DuplicateColumnNameError
            If the new column already exists.
        ColumnSizeError
            If the size of the column does not match the number of rows.
        """
        return TaggedTable._from_table(
            super().add_column(column),
            target_name=self.target.name,
            feature_names=[*self.features.column_names, column.name],
        )

    def add_columns_as_features(self, columns: list[Column] | Table) -> TaggedTable:
        """
        Return a new `TaggedTable` with the provided columns attached at the end, as feature columns.

        The original table is not modified.

        Parameters
        ----------
        columns : list[Column] | Table
            The columns to be added as features.

        Returns
        -------
        result : TaggedTable
            The table with the attached feature columns.

        Raises
        ------
        DuplicateColumnNameError
            If any of the new feature columns already exist.
        ColumnSizeError
            If the size of any feature column does not match the number of rows.
        """
        return TaggedTable._from_table(
            super().add_columns(columns),
            target_name=self.target.name,
            feature_names=self.features.column_names
            + [col.name for col in (columns.to_columns() if isinstance(columns, Table) else columns)],
        )

    # ------------------------------------------------------------------------------------------------------------------
    # Overriden methods from Table class:
    # ------------------------------------------------------------------------------------------------------------------

    def _as_table(self: TaggedTable) -> Table:
        """
        Return a new `Table` with the tagging removed.

        The original TaggedTable is not modified.

        Parameters
        ----------
        self: TaggedTable
            The TaggedTable.

        Returns
        -------
        table: Table
            The table as an untagged Table, i.e. without the information about which columns are features or target.

        """
        return Table.from_columns(super().to_columns())

    def add_column(self, column: Column) -> TaggedTable:
        """
        Return a new `TaggedTable` with the provided column attached at the end, as neither target nor feature column.

        The original table is not modified.

        Parameters
        ----------
        column : Column
            The column to be added.

        Returns
        -------
        result : TaggedTable
            The table with the column attached as neither target nor feature column.

        Raises
        ------
        DuplicateColumnNameError
            If the new column already exists.
        ColumnSizeError
            If the size of the column does not match the number of rows.
        """
        return TaggedTable._from_table(
            super().add_column(column),
            target_name=self.target.name,
            feature_names=self.features.column_names,
        )

    def add_columns(self, columns: list[Column] | Table) -> TaggedTable:
        """
        Return a new `TaggedTable` with multiple added columns, as neither target nor feature columns.

        The original table is not modified.

        Parameters
        ----------
        columns : list[Column] or Table
            The columns to be added.

        Returns
        -------
        result: TaggedTable
            A new table combining the original table and the given columns as neither target nor feature columns.

        Raises
        ------
        DuplicateColumnNameError
            If at least one column name from the provided column list already exists in the table.
        ColumnSizeError
            If at least one of the column sizes from the provided column list does not match the table.
        """
        return TaggedTable._from_table(
            super().add_columns(columns),
            target_name=self.target.name,
            feature_names=self.features.column_names,
        )

    def add_row(self, row: Row) -> TaggedTable:
        """
        Return a new `TaggedTable` with an added Row attached.

        The original table is not modified.

        Parameters
        ----------
        row : Row
            The row to be added.

        Returns
        -------
        table : TaggedTable
            A new tagged table with the added row at the end.

        Raises
        ------
        UnknownColumnNameError
            If the row has different column names than the table.
        """
        return TaggedTable._from_table(super().add_row(row), target_name=self.target.name)

    def add_rows(self, rows: list[Row] | Table) -> TaggedTable:
        """
        Return a new `TaggedTable` with multiple added Rows attached.

        The original table is not modified.

        Parameters
        ----------
        rows : list[Row] or Table
            The rows to be added.

        Returns
        -------
        result : TaggedTable
            A new tagged table which combines the original table and the given rows.

        Raises
        ------
        UnknownColumnNameError
            If at least one of the rows have different column names than the table.
        """
        return TaggedTable._from_table(super().add_rows(rows), target_name=self.target.name)

    def filter_rows(self, query: Callable[[Row], bool]) -> TaggedTable:
        """
        Return a new `TaggedTable` containing only rows that match the given Callable (e.g. lambda function).

        The original tagged table is not modified.

        Parameters
        ----------
        query : lambda function
            A Callable that is applied to all rows.

        Returns
        -------
        result : TaggedTable
            A new tagged table containing only the rows to match the query.
        """
        return TaggedTable._from_table(
            super().filter_rows(query),
            target_name=self.target.name,
            feature_names=self.features.column_names,
        )

    def keep_only_columns(self, column_names: list[str]) -> TaggedTable:
        """
        Return a new `TaggedTable` with only the given column(s).

        The original table is not modified.

        Parameters
        ----------
        column_names : list[str]
            A list containing only the columns to be kept.

        Returns
        -------
        table : TaggedTable
            A table containing only the given column(s).

        Raises
        ------
        UnknownColumnNameError
            If any of the given columns does not exist.
        IllegalSchemaModificationError
            If none of the given columns is the target column or any of the feature columns.
        """
        if self.target.name not in column_names:
            raise IllegalSchemaModificationError("Must keep the target column.")
        if len(set(self.features.column_names).intersection(set(column_names))) == 0:
            raise IllegalSchemaModificationError("Must keep at least one feature column.")
        return TaggedTable._from_table(
            super().keep_only_columns(column_names),
            target_name=self.target.name,
            feature_names=sorted(
                set(self.features.column_names).intersection(set(column_names)),
                key={val: ix for ix, val in enumerate(self.features.column_names)}.__getitem__,
            ),
        )

    def remove_columns(self, column_names: list[str]) -> TaggedTable:
        """
        Return a new `TaggedTable` with the given column(s) removed from the table.

        The original table is not modified.

        Parameters
        ----------
        column_names : list[str]
            The names of all columns to be dropped.

        Returns
        -------
        table : TaggedTable
            A table without the given columns.

        Raises
        ------
        UnknownColumnNameError
            If any of the given columns does not exist.
        ColumnIsTargetError
            If any of the given columns is the target column.
        IllegalSchemaModificationError
            If the given columns contain all the feature columns.
        """
        if self.target.name in column_names:
            raise ColumnIsTargetError(self.target.name)
        if len(set(self.features.column_names) - set(column_names)) == 0:
            raise IllegalSchemaModificationError("You cannot remove every feature column.")
        return TaggedTable._from_table(
            super().remove_columns(column_names),
            target_name=self.target.name,
            feature_names=sorted(
                set(self.features.column_names) - set(column_names),
                key={val: ix for ix, val in enumerate(self.features.column_names)}.__getitem__,
            ),
        )

    def remove_columns_with_missing_values(self) -> TaggedTable:
        """
        Return a new `TaggedTable` with every column that misses values removed.

        The original table is not modified.

        Returns
        -------
        table : TaggedTable
            A table without the columns that contain missing values.

        Raises
        ------
        ColumnIsTargetError
            If any of the columns to be removed is the target column.
        IllegalSchemaModificationError
            If the columns to remove contain all the feature columns.
        """
        table = super().remove_columns_with_missing_values()
        if self.target.name not in table.column_names:
            raise ColumnIsTargetError(self.target.name)
        if len(set(self.features.column_names).intersection(set(table.column_names))) == 0:
            raise IllegalSchemaModificationError("You cannot remove every feature column.")
        return TaggedTable._from_table(
            table,
            self.target.name,
            feature_names=sorted(
                set(self.features.column_names).intersection(set(table.column_names)),
                key={val: ix for ix, val in enumerate(self.features.column_names)}.__getitem__,
            ),
        )

    def remove_columns_with_non_numerical_values(self) -> TaggedTable:
        """
        Return a new `TaggedTable` with every column that contains non-numerical values removed.

        The original table is not modified.

        Returns
        -------
        table : TaggedTable
            A table without the columns that contain non-numerical values.

        Raises
        ------
        ColumnIsTargetError
            If any of the columns to be removed is the target column.
        IllegalSchemaModificationError
            If the columns to remove contain all the feature columns.
        """
        table = super().remove_columns_with_non_numerical_values()
        if self.target.name not in table.column_names:
            raise ColumnIsTargetError(self.target.name)
        if len(set(self.features.column_names).intersection(set(table.column_names))) == 0:
            raise IllegalSchemaModificationError("You cannot remove every feature column.")
        return TaggedTable._from_table(
            table,
            self.target.name,
            feature_names=sorted(
                set(self.features.column_names).intersection(set(table.column_names)),
                key={val: ix for ix, val in enumerate(self.features.column_names)}.__getitem__,
            ),
        )

    def remove_duplicate_rows(self) -> TaggedTable:
        """
        Return a new `TaggedTable` with all row duplicates removed.

        The original table is not modified.

        Returns
        -------
        result : TaggedTable
            The table with the duplicate rows removed.
        """
        return TaggedTable._from_table(
            super().remove_duplicate_rows(),
            target_name=self.target.name,
            feature_names=self.features.column_names,
        )

    def remove_rows_with_missing_values(self) -> TaggedTable:
        """
        Return a new `TaggedTable` without the rows that contain missing values.

        The original table is not modified.

        Returns
        -------
        table : TaggedTable
            A table without the rows that contain missing values.
        """
        return TaggedTable._from_table(
            super().remove_rows_with_missing_values(),
            target_name=self.target.name,
            feature_names=self.features.column_names,
        )

    def remove_rows_with_outliers(self) -> TaggedTable:
        """
        Return a new `TaggedTable` with all rows that contain at least one outlier removed.

        We define an outlier as a value that has a distance of more than 3 standard deviations from the column mean.
        Missing values are not considered outliers. They are also ignored during the calculation of the standard
        deviation.

        The original table is not modified.

        Returns
        -------
        new_table : TaggedTable
            A new table without rows containing outliers.
        """
        return TaggedTable._from_table(
            super().remove_rows_with_outliers(),
            target_name=self.target.name,
            feature_names=self.features.column_names,
        )

    def rename_column(self, old_name: str, new_name: str) -> TaggedTable:
        """
        Return a new `TaggedTable` with a single column renamed.

        The original table is not modified.

        Parameters
        ----------
        old_name : str
            The old name of the target column.
        new_name : str
            The new name of the target column.

        Returns
        -------
        table : TaggedTable
            The Table with the renamed column.

        Raises
        ------
        UnknownColumnNameError
            If the specified old target column name does not exist.
        DuplicateColumnNameError
            If the specified new target column name already exists.
        """
        return TaggedTable._from_table(
            super().rename_column(old_name, new_name),
            target_name=new_name if self.target.name == old_name else self.target.name,
            feature_names=(
                self.features.column_names
                if old_name not in self.features.column_names
                else [
                    column_name if column_name != old_name else new_name for column_name in self.features.column_names
                ]
            ),
        )

    def replace_column(self, old_column_name: str, new_columns: list[Column]) -> TaggedTable:
        """
        Return a new `TaggedTable` with the specified old column replaced by a list of new columns.

        If the column to be replaced is the target column, it must be replaced by exactly one column. That column
        becomes the new target column. If the column to be replaced is a feature column, the new columns that replace it
        all become feature columns.

        The order of columns is kept. The original table is not modified.

        Parameters
        ----------
        old_column_name : str
            The name of the column to be replaced.
        new_columns : list[Column]
            The new columns replacing the old column.

        Returns
        -------
        result : TaggedTable
            A table with the old column replaced by the new column.

        Raises
        ------
        UnknownColumnNameError
            If the old column does not exist.
        DuplicateColumnNameError
            If the new column already exists and the existing column is not affected by the replacement.
        ColumnSizeError
            If the size of the column does not match the amount of rows.
        IllegalSchemaModificationError
            If the target column would be removed or replaced by more than one column.
        """
        if old_column_name == self.target.name:
            if len(new_columns) != 1:
                raise IllegalSchemaModificationError(
                    f'Target column "{self.target.name}" can only be replaced by exactly one new column.',
                )
            else:
                return TaggedTable._from_table(
                    super().replace_column(old_column_name, new_columns),
                    target_name=new_columns[0].name,
                    feature_names=self.features.column_names,
                )
        else:
            return TaggedTable._from_table(
                super().replace_column(old_column_name, new_columns),
                target_name=self.target.name,
                feature_names=(
                    self.features.column_names
                    if old_column_name not in self.features.column_names
                    else self.features.column_names[: self.features.column_names.index(old_column_name)]
                    + [col.name for col in new_columns]
                    + self.features.column_names[self.features.column_names.index(old_column_name) + 1 :]
                ),
            )

    def shuffle_rows(self) -> TaggedTable:
        """
        Return a new `TaggedTable` with randomly shuffled rows of this table.

        The original table is not modified.

        Returns
        -------
        result : TaggedTable
            The shuffled Table.
        """
        return TaggedTable._from_table(
            super().shuffle_rows(),
            target_name=self.target.name,
            feature_names=self.features.column_names,
        )

    def slice_rows(
        self,
        start: int | None = None,
        end: int | None = None,
        step: int = 1,
    ) -> TaggedTable:
        """
        Slice a part of the table into a new `TaggedTable`.

        The original table is not modified.

        Parameters
        ----------
        start : int | None
            The first index of the range to be copied into a new table, None by default.
        end : int | None
            The last index of the range to be copied into a new table, None by default.
        step : int
            The step size used to iterate through the table, 1 by default.

        Returns
        -------
        result : TaggedTable
            The resulting table.

        Raises
        ------
        IndexOutOfBoundsError
            If the index is out of bounds.
        """
        return TaggedTable._from_table(
            super().slice_rows(start, end, step),
            target_name=self.target.name,
            feature_names=self.features.column_names,
        )

    def sort_columns(
        self,
        comparator: Callable[[Column, Column], int] = lambda col1, col2: (col1.name > col2.name)
        - (col1.name < col2.name),
    ) -> TaggedTable:
        """
        Sort the columns of a `TaggedTable` with the given comparator and return a new `TaggedTable`.

        The comparator is a function that takes two columns `col1` and `col2` and
        returns an integer:

        * If the function returns a negative number, `col1` will be ordered before `col2`.
        * If the function returns a positive number, `col1` will be ordered after `col2`.
        * If the function returns 0, the original order of `col1` and `col2` will be kept.

        If no comparator is given, the columns will be sorted alphabetically by their name.

        The original table is not modified.

        Parameters
        ----------
        comparator : Callable[[Column, Column], int]
            The function used to compare two columns.

        Returns
        -------
        new_table : TaggedTable
            A new table with sorted columns.
        """
        sorted_table = super().sort_columns(comparator)
        return TaggedTable._from_table(
            sorted_table,
            target_name=self.target.name,
            feature_names=sorted(
                set(sorted_table.column_names).intersection(self.features.column_names),
                key={val: ix for ix, val in enumerate(sorted_table.column_names)}.__getitem__,
            ),
        )

    def sort_rows(self, comparator: Callable[[Row, Row], int]) -> TaggedTable:
        """
        Sort the rows of a `TaggedTable` with the given comparator and return a new `TaggedTable`.

        The comparator is a function that takes two rows `row1` and `row2` and
        returns an integer:

        * If the function returns a negative number, `row1` will be ordered before `row2`.
        * If the function returns a positive number, `row1` will be ordered after `row2`.
        * If the function returns 0, the original order of `row1` and `row2` will be kept.

        The original table is not modified.

        Parameters
        ----------
        comparator : Callable[[Row, Row], int]
            The function used to compare two rows.

        Returns
        -------
        new_table : TaggedTable
            A new table with sorted rows.
        """
        return TaggedTable._from_table(
            super().sort_rows(comparator),
            target_name=self.target.name,
            feature_names=self.features.column_names,
        )

    def transform_column(self, name: str, transformer: Callable[[Row], Any]) -> TaggedTable:
        """
        Return a new `TaggedTable` with the provided column transformed by calling the provided transformer.

        The original table is not modified.

        Returns
        -------
        result : TaggedTable
            The table with the transformed column.

        Raises
        ------
        UnknownColumnNameError
            If the column does not exist.
        """
        return TaggedTable._from_table(
            super().transform_column(name, transformer),
            target_name=self.target.name,
            feature_names=self.features.column_names,
        )

    def _into_dataloader_with_classes(self, batch_size: int, num_of_classes: int) -> DataLoader:
        """
        Return a Dataloader for the data stored in this table, used for training neural networks.

        The original table is not modified.

        Parameters
        ----------
        batch_size
            The size of data batches that should be loaded at one time.

        Returns
        -------
        result :
            The DataLoader.

        """
        import torch
        from torch.utils.data import DataLoader

        if num_of_classes <= 2:
            return DataLoader(
                dataset=_create_dataset(
                    torch.Tensor(self.features._data.values),
                    torch.Tensor(self.target._data).unsqueeze(dim=-1),
                ),
                batch_size=batch_size,
                shuffle=True,
            )
        else:
            return DataLoader(
                dataset=_create_dataset(
                    torch.Tensor(self.features._data.values),
                    torch.nn.functional.one_hot(torch.LongTensor(self.target._data), num_classes=num_of_classes),
                ),
                batch_size=batch_size,
                shuffle=True,
            )

features: Table property

Get the feature columns of the tagged table.

Returns:

Type Description
Table

The table containing the feature columns.

target: Column property

Get the target column of the tagged table.

Returns:

Type Description
Column

The target column.

__eq__(other)

Compare two tagged table instances.

Returns:

Type Description
'True' if contents and tags are equal, 'False' otherwise.
Source code in src/safeds/data/tabular/containers/_tagged_table.py
def __eq__(self, other: object) -> bool:
    """
    Compare two tagged table instances.

    Returns
    -------
    'True' if contents and tags are equal, 'False' otherwise.
    """
    if not isinstance(other, TaggedTable):
        return NotImplemented
    if self is other:
        return True
    return self.target == other.target and self.features == other.features and Table.__eq__(self, other)

__hash__()

Return a deterministic hash value for this tagged table.

Returns:

Name Type Description
hash int

The hash value.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def __hash__(self) -> int:
    """
    Return a deterministic hash value for this tagged table.

    Returns
    -------
    hash:
        The hash value.
    """
    return _structural_hash(self.target, self.features, Table.__hash__(self))

__init__(data, target_name, feature_names=None)

Create a tagged table from a mapping of column names to their values.

Parameters:

Name Type Description Default
data Mapping[str, Sequence[Any]]

The data.

required
target_name str

Name of the target column.

required
feature_names list[str] | None

Names of the feature columns. If None, all columns except the target column are used.

None

Raises:

Type Description
ColumnLengthMismatchError

If columns have different lengths.

ValueError

If the target column is also a feature column.

ValueError

If no feature columns are specified.

Examples:

>>> from safeds.data.tabular.containers import TaggedTable
>>> table = TaggedTable({"a": [1, 2, 3], "b": [4, 5, 6]}, "b", ["a"])
Source code in src/safeds/data/tabular/containers/_tagged_table.py
def __init__(
    self,
    data: Mapping[str, Sequence[Any]],
    target_name: str,
    feature_names: list[str] | None = None,
):
    """
    Create a tagged table from a mapping of column names to their values.

    Parameters
    ----------
    data : Mapping[str, Sequence[Any]]
        The data.
    target_name : str
        Name of the target column.
    feature_names : list[str] | None
        Names of the feature columns. If None, all columns except the target column are used.

    Raises
    ------
    ColumnLengthMismatchError
        If columns have different lengths.
    ValueError
        If the target column is also a feature column.
    ValueError
        If no feature columns are specified.

    Examples
    --------
    >>> from safeds.data.tabular.containers import TaggedTable
    >>> table = TaggedTable({"a": [1, 2, 3], "b": [4, 5, 6]}, "b", ["a"])
    """
    super().__init__(data)
    _data = Table(data)

    # If no feature names are specified, use all columns except the target column
    if feature_names is None:
        feature_names = _data.column_names
        if target_name in feature_names:
            feature_names.remove(target_name)

    # Validate inputs
    if target_name in feature_names:
        raise ValueError(f"Column '{target_name}' cannot be both feature and target.")
    if len(feature_names) == 0:
        raise ValueError("At least one feature column must be specified.")

    self._features: Table = _data.keep_only_columns(feature_names)
    self._target: Column = _data.get_column(target_name)

__sizeof__()

Return the complete size of this object.

Returns:

Name Type Description
size int

Size of this object in bytes.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def __sizeof__(self) -> int:
    """
    Return the complete size of this object.

    Returns
    -------
    size:
        Size of this object in bytes.
    """
    return Table.__sizeof__(self) + sys.getsizeof(self._features) + sys.getsizeof(self._target)

add_column(column)

Return a new TaggedTable with the provided column attached at the end, as neither target nor feature column.

The original table is not modified.

Parameters:

Name Type Description Default
column Column

The column to be added.

required

Returns:

Name Type Description
result TaggedTable

The table with the column attached as neither target nor feature column.

Raises:

Type Description
DuplicateColumnNameError

If the new column already exists.

ColumnSizeError

If the size of the column does not match the number of rows.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def add_column(self, column: Column) -> TaggedTable:
    """
    Return a new `TaggedTable` with the provided column attached at the end, as neither target nor feature column.

    The original table is not modified.

    Parameters
    ----------
    column : Column
        The column to be added.

    Returns
    -------
    result : TaggedTable
        The table with the column attached as neither target nor feature column.

    Raises
    ------
    DuplicateColumnNameError
        If the new column already exists.
    ColumnSizeError
        If the size of the column does not match the number of rows.
    """
    return TaggedTable._from_table(
        super().add_column(column),
        target_name=self.target.name,
        feature_names=self.features.column_names,
    )

add_column_as_feature(column)

Return a new table with the provided column attached at the end, as a feature column.

the original table is not modified.

Parameters:

Name Type Description Default
column Column

The column to be added.

required

Returns:

Name Type Description
result TaggedTable

The table with the attached feature column.

Raises:

Type Description
DuplicateColumnNameError

If the new column already exists.

ColumnSizeError

If the size of the column does not match the number of rows.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def add_column_as_feature(self, column: Column) -> TaggedTable:
    """
    Return a new table with the provided column attached at the end, as a feature column.

    the original table is not modified.

    Parameters
    ----------
    column : Column
        The column to be added.

    Returns
    -------
    result : TaggedTable
        The table with the attached feature column.

    Raises
    ------
    DuplicateColumnNameError
        If the new column already exists.
    ColumnSizeError
        If the size of the column does not match the number of rows.
    """
    return TaggedTable._from_table(
        super().add_column(column),
        target_name=self.target.name,
        feature_names=[*self.features.column_names, column.name],
    )

add_columns(columns)

Return a new TaggedTable with multiple added columns, as neither target nor feature columns.

The original table is not modified.

Parameters:

Name Type Description Default
columns list[Column] or Table

The columns to be added.

required

Returns:

Name Type Description
result TaggedTable

A new table combining the original table and the given columns as neither target nor feature columns.

Raises:

Type Description
DuplicateColumnNameError

If at least one column name from the provided column list already exists in the table.

ColumnSizeError

If at least one of the column sizes from the provided column list does not match the table.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def add_columns(self, columns: list[Column] | Table) -> TaggedTable:
    """
    Return a new `TaggedTable` with multiple added columns, as neither target nor feature columns.

    The original table is not modified.

    Parameters
    ----------
    columns : list[Column] or Table
        The columns to be added.

    Returns
    -------
    result: TaggedTable
        A new table combining the original table and the given columns as neither target nor feature columns.

    Raises
    ------
    DuplicateColumnNameError
        If at least one column name from the provided column list already exists in the table.
    ColumnSizeError
        If at least one of the column sizes from the provided column list does not match the table.
    """
    return TaggedTable._from_table(
        super().add_columns(columns),
        target_name=self.target.name,
        feature_names=self.features.column_names,
    )

add_columns_as_features(columns)

Return a new TaggedTable with the provided columns attached at the end, as feature columns.

The original table is not modified.

Parameters:

Name Type Description Default
columns list[Column] | Table

The columns to be added as features.

required

Returns:

Name Type Description
result TaggedTable

The table with the attached feature columns.

Raises:

Type Description
DuplicateColumnNameError

If any of the new feature columns already exist.

ColumnSizeError

If the size of any feature column does not match the number of rows.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def add_columns_as_features(self, columns: list[Column] | Table) -> TaggedTable:
    """
    Return a new `TaggedTable` with the provided columns attached at the end, as feature columns.

    The original table is not modified.

    Parameters
    ----------
    columns : list[Column] | Table
        The columns to be added as features.

    Returns
    -------
    result : TaggedTable
        The table with the attached feature columns.

    Raises
    ------
    DuplicateColumnNameError
        If any of the new feature columns already exist.
    ColumnSizeError
        If the size of any feature column does not match the number of rows.
    """
    return TaggedTable._from_table(
        super().add_columns(columns),
        target_name=self.target.name,
        feature_names=self.features.column_names
        + [col.name for col in (columns.to_columns() if isinstance(columns, Table) else columns)],
    )

add_row(row)

Return a new TaggedTable with an added Row attached.

The original table is not modified.

Parameters:

Name Type Description Default
row Row

The row to be added.

required

Returns:

Name Type Description
table TaggedTable

A new tagged table with the added row at the end.

Raises:

Type Description
UnknownColumnNameError

If the row has different column names than the table.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def add_row(self, row: Row) -> TaggedTable:
    """
    Return a new `TaggedTable` with an added Row attached.

    The original table is not modified.

    Parameters
    ----------
    row : Row
        The row to be added.

    Returns
    -------
    table : TaggedTable
        A new tagged table with the added row at the end.

    Raises
    ------
    UnknownColumnNameError
        If the row has different column names than the table.
    """
    return TaggedTable._from_table(super().add_row(row), target_name=self.target.name)

add_rows(rows)

Return a new TaggedTable with multiple added Rows attached.

The original table is not modified.

Parameters:

Name Type Description Default
rows list[Row] or Table

The rows to be added.

required

Returns:

Name Type Description
result TaggedTable

A new tagged table which combines the original table and the given rows.

Raises:

Type Description
UnknownColumnNameError

If at least one of the rows have different column names than the table.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def add_rows(self, rows: list[Row] | Table) -> TaggedTable:
    """
    Return a new `TaggedTable` with multiple added Rows attached.

    The original table is not modified.

    Parameters
    ----------
    rows : list[Row] or Table
        The rows to be added.

    Returns
    -------
    result : TaggedTable
        A new tagged table which combines the original table and the given rows.

    Raises
    ------
    UnknownColumnNameError
        If at least one of the rows have different column names than the table.
    """
    return TaggedTable._from_table(super().add_rows(rows), target_name=self.target.name)

filter_rows(query)

Return a new TaggedTable containing only rows that match the given Callable (e.g. lambda function).

The original tagged table is not modified.

Parameters:

Name Type Description Default
query lambda function

A Callable that is applied to all rows.

required

Returns:

Name Type Description
result TaggedTable

A new tagged table containing only the rows to match the query.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def filter_rows(self, query: Callable[[Row], bool]) -> TaggedTable:
    """
    Return a new `TaggedTable` containing only rows that match the given Callable (e.g. lambda function).

    The original tagged table is not modified.

    Parameters
    ----------
    query : lambda function
        A Callable that is applied to all rows.

    Returns
    -------
    result : TaggedTable
        A new tagged table containing only the rows to match the query.
    """
    return TaggedTable._from_table(
        super().filter_rows(query),
        target_name=self.target.name,
        feature_names=self.features.column_names,
    )

keep_only_columns(column_names)

Return a new TaggedTable with only the given column(s).

The original table is not modified.

Parameters:

Name Type Description Default
column_names list[str]

A list containing only the columns to be kept.

required

Returns:

Name Type Description
table TaggedTable

A table containing only the given column(s).

Raises:

Type Description
UnknownColumnNameError

If any of the given columns does not exist.

IllegalSchemaModificationError

If none of the given columns is the target column or any of the feature columns.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def keep_only_columns(self, column_names: list[str]) -> TaggedTable:
    """
    Return a new `TaggedTable` with only the given column(s).

    The original table is not modified.

    Parameters
    ----------
    column_names : list[str]
        A list containing only the columns to be kept.

    Returns
    -------
    table : TaggedTable
        A table containing only the given column(s).

    Raises
    ------
    UnknownColumnNameError
        If any of the given columns does not exist.
    IllegalSchemaModificationError
        If none of the given columns is the target column or any of the feature columns.
    """
    if self.target.name not in column_names:
        raise IllegalSchemaModificationError("Must keep the target column.")
    if len(set(self.features.column_names).intersection(set(column_names))) == 0:
        raise IllegalSchemaModificationError("Must keep at least one feature column.")
    return TaggedTable._from_table(
        super().keep_only_columns(column_names),
        target_name=self.target.name,
        feature_names=sorted(
            set(self.features.column_names).intersection(set(column_names)),
            key={val: ix for ix, val in enumerate(self.features.column_names)}.__getitem__,
        ),
    )

remove_columns(column_names)

Return a new TaggedTable with the given column(s) removed from the table.

The original table is not modified.

Parameters:

Name Type Description Default
column_names list[str]

The names of all columns to be dropped.

required

Returns:

Name Type Description
table TaggedTable

A table without the given columns.

Raises:

Type Description
UnknownColumnNameError

If any of the given columns does not exist.

ColumnIsTargetError

If any of the given columns is the target column.

IllegalSchemaModificationError

If the given columns contain all the feature columns.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def remove_columns(self, column_names: list[str]) -> TaggedTable:
    """
    Return a new `TaggedTable` with the given column(s) removed from the table.

    The original table is not modified.

    Parameters
    ----------
    column_names : list[str]
        The names of all columns to be dropped.

    Returns
    -------
    table : TaggedTable
        A table without the given columns.

    Raises
    ------
    UnknownColumnNameError
        If any of the given columns does not exist.
    ColumnIsTargetError
        If any of the given columns is the target column.
    IllegalSchemaModificationError
        If the given columns contain all the feature columns.
    """
    if self.target.name in column_names:
        raise ColumnIsTargetError(self.target.name)
    if len(set(self.features.column_names) - set(column_names)) == 0:
        raise IllegalSchemaModificationError("You cannot remove every feature column.")
    return TaggedTable._from_table(
        super().remove_columns(column_names),
        target_name=self.target.name,
        feature_names=sorted(
            set(self.features.column_names) - set(column_names),
            key={val: ix for ix, val in enumerate(self.features.column_names)}.__getitem__,
        ),
    )

remove_columns_with_missing_values()

Return a new TaggedTable with every column that misses values removed.

The original table is not modified.

Returns:

Name Type Description
table TaggedTable

A table without the columns that contain missing values.

Raises:

Type Description
ColumnIsTargetError

If any of the columns to be removed is the target column.

IllegalSchemaModificationError

If the columns to remove contain all the feature columns.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def remove_columns_with_missing_values(self) -> TaggedTable:
    """
    Return a new `TaggedTable` with every column that misses values removed.

    The original table is not modified.

    Returns
    -------
    table : TaggedTable
        A table without the columns that contain missing values.

    Raises
    ------
    ColumnIsTargetError
        If any of the columns to be removed is the target column.
    IllegalSchemaModificationError
        If the columns to remove contain all the feature columns.
    """
    table = super().remove_columns_with_missing_values()
    if self.target.name not in table.column_names:
        raise ColumnIsTargetError(self.target.name)
    if len(set(self.features.column_names).intersection(set(table.column_names))) == 0:
        raise IllegalSchemaModificationError("You cannot remove every feature column.")
    return TaggedTable._from_table(
        table,
        self.target.name,
        feature_names=sorted(
            set(self.features.column_names).intersection(set(table.column_names)),
            key={val: ix for ix, val in enumerate(self.features.column_names)}.__getitem__,
        ),
    )

remove_columns_with_non_numerical_values()

Return a new TaggedTable with every column that contains non-numerical values removed.

The original table is not modified.

Returns:

Name Type Description
table TaggedTable

A table without the columns that contain non-numerical values.

Raises:

Type Description
ColumnIsTargetError

If any of the columns to be removed is the target column.

IllegalSchemaModificationError

If the columns to remove contain all the feature columns.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def remove_columns_with_non_numerical_values(self) -> TaggedTable:
    """
    Return a new `TaggedTable` with every column that contains non-numerical values removed.

    The original table is not modified.

    Returns
    -------
    table : TaggedTable
        A table without the columns that contain non-numerical values.

    Raises
    ------
    ColumnIsTargetError
        If any of the columns to be removed is the target column.
    IllegalSchemaModificationError
        If the columns to remove contain all the feature columns.
    """
    table = super().remove_columns_with_non_numerical_values()
    if self.target.name not in table.column_names:
        raise ColumnIsTargetError(self.target.name)
    if len(set(self.features.column_names).intersection(set(table.column_names))) == 0:
        raise IllegalSchemaModificationError("You cannot remove every feature column.")
    return TaggedTable._from_table(
        table,
        self.target.name,
        feature_names=sorted(
            set(self.features.column_names).intersection(set(table.column_names)),
            key={val: ix for ix, val in enumerate(self.features.column_names)}.__getitem__,
        ),
    )

remove_duplicate_rows()

Return a new TaggedTable with all row duplicates removed.

The original table is not modified.

Returns:

Name Type Description
result TaggedTable

The table with the duplicate rows removed.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def remove_duplicate_rows(self) -> TaggedTable:
    """
    Return a new `TaggedTable` with all row duplicates removed.

    The original table is not modified.

    Returns
    -------
    result : TaggedTable
        The table with the duplicate rows removed.
    """
    return TaggedTable._from_table(
        super().remove_duplicate_rows(),
        target_name=self.target.name,
        feature_names=self.features.column_names,
    )

remove_rows_with_missing_values()

Return a new TaggedTable without the rows that contain missing values.

The original table is not modified.

Returns:

Name Type Description
table TaggedTable

A table without the rows that contain missing values.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def remove_rows_with_missing_values(self) -> TaggedTable:
    """
    Return a new `TaggedTable` without the rows that contain missing values.

    The original table is not modified.

    Returns
    -------
    table : TaggedTable
        A table without the rows that contain missing values.
    """
    return TaggedTable._from_table(
        super().remove_rows_with_missing_values(),
        target_name=self.target.name,
        feature_names=self.features.column_names,
    )

remove_rows_with_outliers()

Return a new TaggedTable with all rows that contain at least one outlier removed.

We define an outlier as a value that has a distance of more than 3 standard deviations from the column mean. Missing values are not considered outliers. They are also ignored during the calculation of the standard deviation.

The original table is not modified.

Returns:

Name Type Description
new_table TaggedTable

A new table without rows containing outliers.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def remove_rows_with_outliers(self) -> TaggedTable:
    """
    Return a new `TaggedTable` with all rows that contain at least one outlier removed.

    We define an outlier as a value that has a distance of more than 3 standard deviations from the column mean.
    Missing values are not considered outliers. They are also ignored during the calculation of the standard
    deviation.

    The original table is not modified.

    Returns
    -------
    new_table : TaggedTable
        A new table without rows containing outliers.
    """
    return TaggedTable._from_table(
        super().remove_rows_with_outliers(),
        target_name=self.target.name,
        feature_names=self.features.column_names,
    )

rename_column(old_name, new_name)

Return a new TaggedTable with a single column renamed.

The original table is not modified.

Parameters:

Name Type Description Default
old_name str

The old name of the target column.

required
new_name str

The new name of the target column.

required

Returns:

Name Type Description
table TaggedTable

The Table with the renamed column.

Raises:

Type Description
UnknownColumnNameError

If the specified old target column name does not exist.

DuplicateColumnNameError

If the specified new target column name already exists.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def rename_column(self, old_name: str, new_name: str) -> TaggedTable:
    """
    Return a new `TaggedTable` with a single column renamed.

    The original table is not modified.

    Parameters
    ----------
    old_name : str
        The old name of the target column.
    new_name : str
        The new name of the target column.

    Returns
    -------
    table : TaggedTable
        The Table with the renamed column.

    Raises
    ------
    UnknownColumnNameError
        If the specified old target column name does not exist.
    DuplicateColumnNameError
        If the specified new target column name already exists.
    """
    return TaggedTable._from_table(
        super().rename_column(old_name, new_name),
        target_name=new_name if self.target.name == old_name else self.target.name,
        feature_names=(
            self.features.column_names
            if old_name not in self.features.column_names
            else [
                column_name if column_name != old_name else new_name for column_name in self.features.column_names
            ]
        ),
    )

replace_column(old_column_name, new_columns)

Return a new TaggedTable with the specified old column replaced by a list of new columns.

If the column to be replaced is the target column, it must be replaced by exactly one column. That column becomes the new target column. If the column to be replaced is a feature column, the new columns that replace it all become feature columns.

The order of columns is kept. The original table is not modified.

Parameters:

Name Type Description Default
old_column_name str

The name of the column to be replaced.

required
new_columns list[Column]

The new columns replacing the old column.

required

Returns:

Name Type Description
result TaggedTable

A table with the old column replaced by the new column.

Raises:

Type Description
UnknownColumnNameError

If the old column does not exist.

DuplicateColumnNameError

If the new column already exists and the existing column is not affected by the replacement.

ColumnSizeError

If the size of the column does not match the amount of rows.

IllegalSchemaModificationError

If the target column would be removed or replaced by more than one column.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def replace_column(self, old_column_name: str, new_columns: list[Column]) -> TaggedTable:
    """
    Return a new `TaggedTable` with the specified old column replaced by a list of new columns.

    If the column to be replaced is the target column, it must be replaced by exactly one column. That column
    becomes the new target column. If the column to be replaced is a feature column, the new columns that replace it
    all become feature columns.

    The order of columns is kept. The original table is not modified.

    Parameters
    ----------
    old_column_name : str
        The name of the column to be replaced.
    new_columns : list[Column]
        The new columns replacing the old column.

    Returns
    -------
    result : TaggedTable
        A table with the old column replaced by the new column.

    Raises
    ------
    UnknownColumnNameError
        If the old column does not exist.
    DuplicateColumnNameError
        If the new column already exists and the existing column is not affected by the replacement.
    ColumnSizeError
        If the size of the column does not match the amount of rows.
    IllegalSchemaModificationError
        If the target column would be removed or replaced by more than one column.
    """
    if old_column_name == self.target.name:
        if len(new_columns) != 1:
            raise IllegalSchemaModificationError(
                f'Target column "{self.target.name}" can only be replaced by exactly one new column.',
            )
        else:
            return TaggedTable._from_table(
                super().replace_column(old_column_name, new_columns),
                target_name=new_columns[0].name,
                feature_names=self.features.column_names,
            )
    else:
        return TaggedTable._from_table(
            super().replace_column(old_column_name, new_columns),
            target_name=self.target.name,
            feature_names=(
                self.features.column_names
                if old_column_name not in self.features.column_names
                else self.features.column_names[: self.features.column_names.index(old_column_name)]
                + [col.name for col in new_columns]
                + self.features.column_names[self.features.column_names.index(old_column_name) + 1 :]
            ),
        )

shuffle_rows()

Return a new TaggedTable with randomly shuffled rows of this table.

The original table is not modified.

Returns:

Name Type Description
result TaggedTable

The shuffled Table.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def shuffle_rows(self) -> TaggedTable:
    """
    Return a new `TaggedTable` with randomly shuffled rows of this table.

    The original table is not modified.

    Returns
    -------
    result : TaggedTable
        The shuffled Table.
    """
    return TaggedTable._from_table(
        super().shuffle_rows(),
        target_name=self.target.name,
        feature_names=self.features.column_names,
    )

slice_rows(start=None, end=None, step=1)

Slice a part of the table into a new TaggedTable.

The original table is not modified.

Parameters:

Name Type Description Default
start int | None

The first index of the range to be copied into a new table, None by default.

None
end int | None

The last index of the range to be copied into a new table, None by default.

None
step int

The step size used to iterate through the table, 1 by default.

1

Returns:

Name Type Description
result TaggedTable

The resulting table.

Raises:

Type Description
IndexOutOfBoundsError

If the index is out of bounds.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def slice_rows(
    self,
    start: int | None = None,
    end: int | None = None,
    step: int = 1,
) -> TaggedTable:
    """
    Slice a part of the table into a new `TaggedTable`.

    The original table is not modified.

    Parameters
    ----------
    start : int | None
        The first index of the range to be copied into a new table, None by default.
    end : int | None
        The last index of the range to be copied into a new table, None by default.
    step : int
        The step size used to iterate through the table, 1 by default.

    Returns
    -------
    result : TaggedTable
        The resulting table.

    Raises
    ------
    IndexOutOfBoundsError
        If the index is out of bounds.
    """
    return TaggedTable._from_table(
        super().slice_rows(start, end, step),
        target_name=self.target.name,
        feature_names=self.features.column_names,
    )

sort_columns(comparator=lambda col1, col2: col1.name > col2.name - col1.name < col2.name)

Sort the columns of a TaggedTable with the given comparator and return a new TaggedTable.

The comparator is a function that takes two columns col1 and col2 and returns an integer:

  • If the function returns a negative number, col1 will be ordered before col2.
  • If the function returns a positive number, col1 will be ordered after col2.
  • If the function returns 0, the original order of col1 and col2 will be kept.

If no comparator is given, the columns will be sorted alphabetically by their name.

The original table is not modified.

Parameters:

Name Type Description Default
comparator Callable[[Column, Column], int]

The function used to compare two columns.

lambda col1, col2: name > name - name < name

Returns:

Name Type Description
new_table TaggedTable

A new table with sorted columns.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def sort_columns(
    self,
    comparator: Callable[[Column, Column], int] = lambda col1, col2: (col1.name > col2.name)
    - (col1.name < col2.name),
) -> TaggedTable:
    """
    Sort the columns of a `TaggedTable` with the given comparator and return a new `TaggedTable`.

    The comparator is a function that takes two columns `col1` and `col2` and
    returns an integer:

    * If the function returns a negative number, `col1` will be ordered before `col2`.
    * If the function returns a positive number, `col1` will be ordered after `col2`.
    * If the function returns 0, the original order of `col1` and `col2` will be kept.

    If no comparator is given, the columns will be sorted alphabetically by their name.

    The original table is not modified.

    Parameters
    ----------
    comparator : Callable[[Column, Column], int]
        The function used to compare two columns.

    Returns
    -------
    new_table : TaggedTable
        A new table with sorted columns.
    """
    sorted_table = super().sort_columns(comparator)
    return TaggedTable._from_table(
        sorted_table,
        target_name=self.target.name,
        feature_names=sorted(
            set(sorted_table.column_names).intersection(self.features.column_names),
            key={val: ix for ix, val in enumerate(sorted_table.column_names)}.__getitem__,
        ),
    )

sort_rows(comparator)

Sort the rows of a TaggedTable with the given comparator and return a new TaggedTable.

The comparator is a function that takes two rows row1 and row2 and returns an integer:

  • If the function returns a negative number, row1 will be ordered before row2.
  • If the function returns a positive number, row1 will be ordered after row2.
  • If the function returns 0, the original order of row1 and row2 will be kept.

The original table is not modified.

Parameters:

Name Type Description Default
comparator Callable[[Row, Row], int]

The function used to compare two rows.

required

Returns:

Name Type Description
new_table TaggedTable

A new table with sorted rows.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def sort_rows(self, comparator: Callable[[Row, Row], int]) -> TaggedTable:
    """
    Sort the rows of a `TaggedTable` with the given comparator and return a new `TaggedTable`.

    The comparator is a function that takes two rows `row1` and `row2` and
    returns an integer:

    * If the function returns a negative number, `row1` will be ordered before `row2`.
    * If the function returns a positive number, `row1` will be ordered after `row2`.
    * If the function returns 0, the original order of `row1` and `row2` will be kept.

    The original table is not modified.

    Parameters
    ----------
    comparator : Callable[[Row, Row], int]
        The function used to compare two rows.

    Returns
    -------
    new_table : TaggedTable
        A new table with sorted rows.
    """
    return TaggedTable._from_table(
        super().sort_rows(comparator),
        target_name=self.target.name,
        feature_names=self.features.column_names,
    )

transform_column(name, transformer)

Return a new TaggedTable with the provided column transformed by calling the provided transformer.

The original table is not modified.

Returns:

Name Type Description
result TaggedTable

The table with the transformed column.

Raises:

Type Description
UnknownColumnNameError

If the column does not exist.

Source code in src/safeds/data/tabular/containers/_tagged_table.py
def transform_column(self, name: str, transformer: Callable[[Row], Any]) -> TaggedTable:
    """
    Return a new `TaggedTable` with the provided column transformed by calling the provided transformer.

    The original table is not modified.

    Returns
    -------
    result : TaggedTable
        The table with the transformed column.

    Raises
    ------
    UnknownColumnNameError
        If the column does not exist.
    """
    return TaggedTable._from_table(
        super().transform_column(name, transformer),
        target_name=self.target.name,
        feature_names=self.features.column_names,
    )