bikes.io.datasets
Read/Write datasets from/to external sources/destinations.
1"""Read/Write datasets from/to external sources/destinations.""" 2 3# %% IMPORTS 4 5import abc 6import typing as T 7 8import mlflow.data.pandas_dataset as lineage 9import mlflow.data.sources as sources 10import pandas as pd 11import pydantic as pdt 12 13# %% TYPINGS 14 15Lineage: T.TypeAlias = lineage.PandasDataset 16 17# %% READERS 18 19 20class Reader(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"): 21 """Base class for a dataset reader. 22 23 Use a reader to load a dataset in memory. 24 e.g., to read file, database, cloud storage, ... 25 26 Parameters: 27 limit (int, optional): maximum number of rows to read. Defaults to None. 28 """ 29 30 KIND: str 31 32 limit: int | None = None 33 34 @abc.abstractmethod 35 def read(self) -> pd.DataFrame: 36 """Read a dataframe from a dataset. 37 38 Returns: 39 pd.DataFrame: dataframe representation. 40 """ 41 42 @abc.abstractmethod 43 def lineage( 44 self, 45 name: str, 46 data: pd.DataFrame, 47 targets: str | None = None, 48 predictions: str | None = None, 49 ) -> Lineage: 50 """Generate lineage information. 51 52 Args: 53 name (str): dataset name. 54 data (pd.DataFrame): reader dataframe. 55 targets (str | None): name of the target column. 56 predictions (str | None): name of the prediction column. 57 58 Returns: 59 Lineage: lineage information. 60 """ 61 62 63class ParquetReader(Reader): 64 """Read a dataframe from a parquet file. 65 66 Parameters: 67 path (str): local path to the dataset. 68 """ 69 70 KIND: T.Literal["ParquetReader"] = "ParquetReader" 71 72 path: str 73 backend: T.Literal["pyarrow", "numpy_nullable"] = "pyarrow" 74 75 @T.override 76 def read(self) -> pd.DataFrame: 77 # can't limit rows at read time 78 data = pd.read_parquet(self.path, dtype_backend=self.backend) 79 if self.limit is not None: 80 data = data.head(self.limit) 81 return data 82 83 @T.override 84 def lineage( 85 self, 86 name: str, 87 data: pd.DataFrame, 88 targets: str | None = None, 89 predictions: str | None = None, 90 ) -> Lineage: 91 return lineage.from_pandas( 92 df=data, 93 name=name, 94 # an explicit source: the path string matches two registered local sources, 95 # and MLflow warns on every lineage while picking one 96 source=sources.LocalArtifactDatasetSource(self.path), 97 targets=targets, 98 predictions=predictions, 99 ) 100 101 102ReaderKind = ParquetReader 103 104# %% WRITERS 105 106 107class Writer(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"): 108 """Base class for a dataset writer. 109 110 Use a writer to save a dataset from memory. 111 e.g., to write file, database, cloud storage, ... 112 """ 113 114 KIND: str 115 116 @abc.abstractmethod 117 def write(self, data: pd.DataFrame) -> None: 118 """Write a dataframe to a dataset. 119 120 Args: 121 data (pd.DataFrame): dataframe representation. 122 """ 123 124 125class ParquetWriter(Writer): 126 """Writer a dataframe to a parquet file. 127 128 Parameters: 129 path (str): local or S3 path to the dataset. 130 """ 131 132 KIND: T.Literal["ParquetWriter"] = "ParquetWriter" 133 134 path: str 135 136 @T.override 137 def write(self, data: pd.DataFrame) -> None: 138 pd.DataFrame.to_parquet(data, self.path) 139 140 141WriterKind = ParquetWriter
Lineage: TypeAlias =
mlflow.data.pandas_dataset.PandasDataset
class
Reader(abc.ABC, pydantic.main.BaseModel):
21class Reader(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"): 22 """Base class for a dataset reader. 23 24 Use a reader to load a dataset in memory. 25 e.g., to read file, database, cloud storage, ... 26 27 Parameters: 28 limit (int, optional): maximum number of rows to read. Defaults to None. 29 """ 30 31 KIND: str 32 33 limit: int | None = None 34 35 @abc.abstractmethod 36 def read(self) -> pd.DataFrame: 37 """Read a dataframe from a dataset. 38 39 Returns: 40 pd.DataFrame: dataframe representation. 41 """ 42 43 @abc.abstractmethod 44 def lineage( 45 self, 46 name: str, 47 data: pd.DataFrame, 48 targets: str | None = None, 49 predictions: str | None = None, 50 ) -> Lineage: 51 """Generate lineage information. 52 53 Args: 54 name (str): dataset name. 55 data (pd.DataFrame): reader dataframe. 56 targets (str | None): name of the target column. 57 predictions (str | None): name of the prediction column. 58 59 Returns: 60 Lineage: lineage information. 61 """
Base class for a dataset reader.
Use a reader to load a dataset in memory. e.g., to read file, database, cloud storage, ...
Arguments:
- limit (int, optional): maximum number of rows to read. Defaults to None.
@abc.abstractmethod
def
read(self) -> pandas.DataFrame:
35 @abc.abstractmethod 36 def read(self) -> pd.DataFrame: 37 """Read a dataframe from a dataset. 38 39 Returns: 40 pd.DataFrame: dataframe representation. 41 """
Read a dataframe from a dataset.
Returns:
pd.DataFrame: dataframe representation.
@abc.abstractmethod
def
lineage( self, name: str, data: pandas.DataFrame, targets: str | None = None, predictions: str | None = None) -> mlflow.data.pandas_dataset.PandasDataset:
43 @abc.abstractmethod 44 def lineage( 45 self, 46 name: str, 47 data: pd.DataFrame, 48 targets: str | None = None, 49 predictions: str | None = None, 50 ) -> Lineage: 51 """Generate lineage information. 52 53 Args: 54 name (str): dataset name. 55 data (pd.DataFrame): reader dataframe. 56 targets (str | None): name of the target column. 57 predictions (str | None): name of the prediction column. 58 59 Returns: 60 Lineage: lineage information. 61 """
Generate lineage information.
Arguments:
- name (str): dataset name.
- data (pd.DataFrame): reader dataframe.
- targets (str | None): name of the target column.
- predictions (str | None): name of the prediction column.
Returns:
Lineage: lineage information.
64class ParquetReader(Reader): 65 """Read a dataframe from a parquet file. 66 67 Parameters: 68 path (str): local path to the dataset. 69 """ 70 71 KIND: T.Literal["ParquetReader"] = "ParquetReader" 72 73 path: str 74 backend: T.Literal["pyarrow", "numpy_nullable"] = "pyarrow" 75 76 @T.override 77 def read(self) -> pd.DataFrame: 78 # can't limit rows at read time 79 data = pd.read_parquet(self.path, dtype_backend=self.backend) 80 if self.limit is not None: 81 data = data.head(self.limit) 82 return data 83 84 @T.override 85 def lineage( 86 self, 87 name: str, 88 data: pd.DataFrame, 89 targets: str | None = None, 90 predictions: str | None = None, 91 ) -> Lineage: 92 return lineage.from_pandas( 93 df=data, 94 name=name, 95 # an explicit source: the path string matches two registered local sources, 96 # and MLflow warns on every lineage while picking one 97 source=sources.LocalArtifactDatasetSource(self.path), 98 targets=targets, 99 predictions=predictions, 100 )
Read a dataframe from a parquet file.
Arguments:
- path (str): local path to the dataset.
@T.override
def
read(self) -> pandas.DataFrame:
76 @T.override 77 def read(self) -> pd.DataFrame: 78 # can't limit rows at read time 79 data = pd.read_parquet(self.path, dtype_backend=self.backend) 80 if self.limit is not None: 81 data = data.head(self.limit) 82 return data
Read a dataframe from a dataset.
Returns:
pd.DataFrame: dataframe representation.
@T.override
def
lineage( self, name: str, data: pandas.DataFrame, targets: str | None = None, predictions: str | None = None) -> mlflow.data.pandas_dataset.PandasDataset:
84 @T.override 85 def lineage( 86 self, 87 name: str, 88 data: pd.DataFrame, 89 targets: str | None = None, 90 predictions: str | None = None, 91 ) -> Lineage: 92 return lineage.from_pandas( 93 df=data, 94 name=name, 95 # an explicit source: the path string matches two registered local sources, 96 # and MLflow warns on every lineage while picking one 97 source=sources.LocalArtifactDatasetSource(self.path), 98 targets=targets, 99 predictions=predictions, 100 )
Generate lineage information.
Arguments:
- name (str): dataset name.
- data (pd.DataFrame): reader dataframe.
- targets (str | None): name of the target column.
- predictions (str | None): name of the prediction column.
Returns:
Lineage: lineage information.
ReaderKind =
<class 'ParquetReader'>
class
Writer(abc.ABC, pydantic.main.BaseModel):
108class Writer(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"): 109 """Base class for a dataset writer. 110 111 Use a writer to save a dataset from memory. 112 e.g., to write file, database, cloud storage, ... 113 """ 114 115 KIND: str 116 117 @abc.abstractmethod 118 def write(self, data: pd.DataFrame) -> None: 119 """Write a dataframe to a dataset. 120 121 Args: 122 data (pd.DataFrame): dataframe representation. 123 """
Base class for a dataset writer.
Use a writer to save a dataset from memory. e.g., to write file, database, cloud storage, ...
@abc.abstractmethod
def
write(self, data: pandas.DataFrame) -> None:
117 @abc.abstractmethod 118 def write(self, data: pd.DataFrame) -> None: 119 """Write a dataframe to a dataset. 120 121 Args: 122 data (pd.DataFrame): dataframe representation. 123 """
Write a dataframe to a dataset.
Arguments:
- data (pd.DataFrame): dataframe representation.
126class ParquetWriter(Writer): 127 """Writer a dataframe to a parquet file. 128 129 Parameters: 130 path (str): local or S3 path to the dataset. 131 """ 132 133 KIND: T.Literal["ParquetWriter"] = "ParquetWriter" 134 135 path: str 136 137 @T.override 138 def write(self, data: pd.DataFrame) -> None: 139 pd.DataFrame.to_parquet(data, self.path)
Writer a dataframe to a parquet file.
Arguments:
- path (str): local or S3 path to the dataset.
WriterKind =
<class 'ParquetWriter'>