diff --git a/spec/API_specification/dataframe_api/column_object.py b/spec/API_specification/dataframe_api/column_object.py index 6a83bbce..c0c054e3 100644 --- a/spec/API_specification/dataframe_api/column_object.py +++ b/spec/API_specification/dataframe_api/column_object.py @@ -5,6 +5,8 @@ if TYPE_CHECKING: from typing_extensions import Self + from dataframe_api.dataframe_object import DataFrame + from .typing import DType, Namespace, NullType, Scalar @@ -17,9 +19,45 @@ class Column(Protocol): Note that this column object is not meant to be instantiated directly by users of the library implementing the dataframe API standard. Rather, use constructor functions or an already-created dataframe object retrieved via - + :meth:`DataFrame.col`. + + The parent dataframe (which can be retrieved via the :meth:`parent_dataframe` + property) plays a key role here: + + - If two columns were retrieved from the same dataframe, + then they can be combined and compared at will. + - If two columns were retrieved from different dataframes, + then there is no guarantee about how or whether they can be combined and + compared, this may vary across implementations. + - If two columns are both "free-standing" (i.e. not retrieved from a dataframe + but constructed directly from a 1D array or sequence), then they can be + combined and compared with each other. Note, however, that there's no guarantee + about whether they can be compared or combined with columns retrieved from a + different dataframe, this may vary across implementations. """ + @property + def parent_dataframe(self) -> DataFrame | None: + """Return parent DataFrame, if present. + + For example, if we have the following + + .. code-block:: python + + df: DataFrame + column = df.col('a') + + then `column.parent_dataframe` should return `df`. + + On the other hand, if we had: + + .. code-block:: python + + column = column_from_1d_array(...) + + then `column.parent_dataframe` should return `None`. + """ + def __column_namespace__(self) -> Namespace: """Return an object that has all the Dataframe Standard API functions on it. @@ -201,6 +239,11 @@ def __eq__(self, other: Self | Scalar) -> Self: # type: ignore[override] Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... @@ -219,6 +262,11 @@ def __ne__(self, other: Self | Scalar) -> Self: # type: ignore[override] Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... @@ -235,6 +283,11 @@ def __ge__(self, other: Self | Scalar) -> Self: Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... @@ -251,6 +304,11 @@ def __gt__(self, other: Self | Scalar) -> Self: Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... @@ -267,6 +325,11 @@ def __le__(self, other: Self | Scalar) -> Self: Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... @@ -283,6 +346,11 @@ def __lt__(self, other: Self | Scalar) -> Self: Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... @@ -300,6 +368,11 @@ def __and__(self, other: Self | bool) -> Self: ------- Column + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. + Raises ------ ValueError @@ -321,6 +394,11 @@ def __or__(self, other: Self | bool) -> Self: ------- Column + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. + Raises ------ ValueError @@ -338,6 +416,11 @@ def __add__(self, other: Self | Scalar) -> Self: "Scalar" here is defined implicitly by what scalar types are allowed for the operation by the underling dtypes. + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. + Returns ------- Column @@ -357,6 +440,11 @@ def __sub__(self, other: Self | Scalar) -> Self: Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... @@ -373,6 +461,11 @@ def __mul__(self, other: Self | Scalar) -> Self: Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... @@ -389,6 +482,11 @@ def __truediv__(self, other: Self | Scalar) -> Self: Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... @@ -405,6 +503,11 @@ def __floordiv__(self, other: Self | Scalar) -> Self: Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... @@ -425,6 +528,11 @@ def __pow__(self, other: Self | Scalar) -> Self: Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... @@ -441,6 +549,11 @@ def __mod__(self, other: Self | Scalar) -> Self: Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... @@ -457,6 +570,11 @@ def __divmod__(self, other: Self | Scalar) -> tuple[Column, Column]: Returns ------- Column + + Notes + ----- + `other`'s parent DataFrame must be the same as `self`'s - else, + the operation is unsupported and may vary across implementations. """ ... diff --git a/spec/API_specification/dataframe_api/dataframe_object.py b/spec/API_specification/dataframe_api/dataframe_object.py index 142090e8..29e6b516 100644 --- a/spec/API_specification/dataframe_api/dataframe_object.py +++ b/spec/API_specification/dataframe_api/dataframe_object.py @@ -136,6 +136,11 @@ def get_rows(self, indices: Column) -> Self: Returns ------- DataFrame + + Notes + ----- + `indices`'s parent DataFrame must be `self` - else, + the operation is unsupported and may vary across implementations. """ ... @@ -172,8 +177,8 @@ def filter(self, mask: Column) -> Self: Notes ----- - Some participants preferred a weaker type Arraylike[bool] for mask, - where 'Arraylike' denotes an object adhering to the Array API standard. + `mask`'s parent DataFrame must be `self` - else, + the operation is unsupported and may vary across implementations. """ ... @@ -201,6 +206,11 @@ def assign(self, *columns: Column) -> Self: Returns ------- DataFrame + + Notes + ----- + All of `columns`'s parent DataFrame must be `self` - else, + the operation is unsupported and may vary across implementations. """ ...