aspect-data 0.0.6__tar.gz → 0.0.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aspect_data-0.0.7/PKG-INFO +1163 -0
- aspect_data-0.0.7/README.md +1097 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/cli_module/cli.py +24 -5
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/cli_module/featurize.py +37 -18
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/collate/base.py +14 -2
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/data.py +147 -247
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/transform/base.py +7 -6
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/typing.py +1 -7
- aspect_data-0.0.7/aspect_data.egg-info/PKG-INFO +1163 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect_data.egg-info/SOURCES.txt +1 -6
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect_data.egg-info/requires.txt +3 -3
- {aspect_data-0.0.6 → aspect_data-0.0.7}/pyproject.toml +5 -4
- {aspect_data-0.0.6 → aspect_data-0.0.7}/test/test_checkpoint.py +63 -60
- {aspect_data-0.0.6 → aspect_data-0.0.7}/test/test_collate.py +2 -2
- aspect_data-0.0.7/test/test_data_source.py +22 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/test/test_dataloader.py +3 -3
- {aspect_data-0.0.6 → aspect_data-0.0.7}/test/test_empty_pipeline.py +5 -5
- aspect_data-0.0.7/test/test_feature_shape.py +21 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/test/test_transform_dict.py +3 -4
- aspect_data-0.0.6/PKG-INFO +0 -931
- aspect_data-0.0.6/README.md +0 -866
- aspect_data-0.0.6/aspect/checkpoint_utils.py +0 -95
- aspect_data-0.0.6/aspect/cli_module/io.py +0 -52
- aspect_data-0.0.6/aspect/io.py +0 -504
- aspect_data-0.0.6/aspect/package_data.py +0 -54
- aspect_data-0.0.6/aspect_data.egg-info/PKG-INFO +0 -931
- aspect_data-0.0.6/test/test_checksum.py +0 -101
- aspect_data-0.0.6/test/test_data_source.py +0 -22
- aspect_data-0.0.6/test/test_io.py +0 -128
- {aspect_data-0.0.6 → aspect_data-0.0.7}/LICENSE +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/__init__.py +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/cli_module/__init__.py +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/collate/__init__.py +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/collate/chemprop.py +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/transform/__init__.py +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/transform/chemprop.py +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/transform/deep_functions.py +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/transform/functions.py +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect/transform/registry.py +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect_data.egg-info/dependency_links.txt +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect_data.egg-info/entry_points.txt +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/aspect_data.egg-info/top_level.txt +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/setup.cfg +0 -0
- {aspect_data-0.0.6 → aspect_data-0.0.7}/test/test_collate_chemprop.py +0 -0
|
@@ -0,0 +1,1163 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aspect-data
|
|
3
|
+
Version: 0.0.7
|
|
4
|
+
Summary: General purpose, chemistry, and taxonomic featurization of tabular data with caching.
|
|
5
|
+
Author-email: Eachan Johnson <eachan.johnson@crick.ac.uk>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) [year] [fullname]
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
Project-URL: Homepage, https://github.com/scbirlab/aspect
|
|
28
|
+
Project-URL: Bug Tracker, https://github.com/scbirlab/aspect/issues
|
|
29
|
+
Keywords: ai,data,deep-learning,machine-learning
|
|
30
|
+
Classifier: Development Status :: 3 - Alpha
|
|
31
|
+
Classifier: Intended Audience :: Science/Research
|
|
32
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
33
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
39
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
40
|
+
Requires-Python: >=3.11
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
42
|
+
License-File: LICENSE
|
|
43
|
+
Requires-Dist: carabiner-tools[mpl,pd]>=0.0.5.post3
|
|
44
|
+
Requires-Dist: datasets>=3.0.0
|
|
45
|
+
Requires-Dist: filelock
|
|
46
|
+
Requires-Dist: huggingface_hub
|
|
47
|
+
Requires-Dist: numpy
|
|
48
|
+
Requires-Dist: providence>=0.0.2
|
|
49
|
+
Requires-Dist: tqdm
|
|
50
|
+
Provides-Extra: chem
|
|
51
|
+
Requires-Dist: schemist>=0.0.7; extra == "chem"
|
|
52
|
+
Provides-Extra: torch
|
|
53
|
+
Requires-Dist: torch>=2.4; extra == "torch"
|
|
54
|
+
Provides-Extra: chemprop
|
|
55
|
+
Requires-Dist: aspect-data[chem,torch]; extra == "chemprop"
|
|
56
|
+
Requires-Dist: chemprop>=2.1.0; extra == "chemprop"
|
|
57
|
+
Provides-Extra: deep
|
|
58
|
+
Requires-Dist: transformers; extra == "deep"
|
|
59
|
+
Provides-Extra: bio
|
|
60
|
+
Requires-Dist: vectome>=0.0.8; extra == "bio"
|
|
61
|
+
Provides-Extra: dev
|
|
62
|
+
Requires-Dist: aspect-data[bio,chemprop]; extra == "dev"
|
|
63
|
+
Requires-Dist: pytest>=7.4; extra == "dev"
|
|
64
|
+
Requires-Dist: flake8; extra == "dev"
|
|
65
|
+
Dynamic: license-file
|
|
66
|
+
|
|
67
|
+
# 🏔️ aspect
|
|
68
|
+
|
|
69
|
+

|
|
70
|
+

|
|
71
|
+

|
|
72
|
+
|
|
73
|
+
<img src="docs/source/_static/logo.svg" width="200">
|
|
74
|
+
|
|
75
|
+
**aspect** is a Python library and command-line tool for reproducible featurisation of tabular machine-learning datasets.
|
|
76
|
+
|
|
77
|
+
It lets you define independent transformation pipelines for different input columns, including molecular structures, taxonomy, categorical variables, and numerical measurements. Pipelines can be serialised, applied to new datasets, checkpointed, and restored.
|
|
78
|
+
|
|
79
|
+
Aspect uses [Providence](https://github.com/scbirlab/providence) for dataset loading, source provenance, and checkpointing, and [Hugging Face Datasets](https://huggingface.co/docs/datasets/) for Arrow-backed data processing and caching.
|
|
80
|
+
|
|
81
|
+
The core idea:
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
Input dataset
|
|
85
|
+
│
|
|
86
|
+
├── SMILES ──────→ Molecular fingerprints
|
|
87
|
+
├── Species ─────→ Taxonomic fingerprints
|
|
88
|
+
├── Assay ───────→ Categorical encoding
|
|
89
|
+
├── MW ──────────→ Log transformation
|
|
90
|
+
└── Description ─→ Language-model embeddings
|
|
91
|
+
│
|
|
92
|
+
▼
|
|
93
|
+
Aspect DataPipeline
|
|
94
|
+
│
|
|
95
|
+
├── Reusable feature specification
|
|
96
|
+
├── Reproducible dataset checkpoint
|
|
97
|
+
└── Optional source materialisation
|
|
98
|
+
│
|
|
99
|
+
▼
|
|
100
|
+
Providence DataResolver
|
|
101
|
+
│
|
|
102
|
+
├── Hugging Face Dataset
|
|
103
|
+
├── Export: CSV / TSV / JSON / Parquet
|
|
104
|
+
└── Model-specific collation / DataLoader
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Feature representations are stored in Arrow-compatible columns. Model-specific collators can convert these stored values into tensors, molecular graphs, or other runtime representations without embedding model-specific logic in dataset preprocessing.
|
|
108
|
+
|
|
109
|
+
## Contents
|
|
110
|
+
|
|
111
|
+
- [Quick start](#quick-start)
|
|
112
|
+
- [Installation](#installation)
|
|
113
|
+
- [Command-line interface](#command-line-interface)
|
|
114
|
+
- [Python API](#python-api)
|
|
115
|
+
- [Feature specifications](#feature-specifications)
|
|
116
|
+
- [Available transforms](#available-transforms)
|
|
117
|
+
- [Saving and loading pipelines](#saving-and-loading-pipelines)
|
|
118
|
+
- [Supported input and output formats](#supported-input-and-output-formats)
|
|
119
|
+
- [Working with output columns](#working-with-output-columns)
|
|
120
|
+
- [Custom transforms](#custom-transforms)
|
|
121
|
+
- [Model integration](#model-integration)
|
|
122
|
+
- [Development](#development)
|
|
123
|
+
- [Issues and documentation](#issues-and-documentation)
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Quick start
|
|
128
|
+
|
|
129
|
+
### 1. Featurise a dataset
|
|
130
|
+
|
|
131
|
+
Create a small CSV:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
cat > compounds.csv <<'CSV'
|
|
135
|
+
compound_id,assay,mwt,pIC50
|
|
136
|
+
cmpd-1,MIC,46.07,5.0
|
|
137
|
+
cmpd-2,MIC,60.10,6.2
|
|
138
|
+
cmpd-3,IC50,78.11,4.8
|
|
139
|
+
CSV
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Generate numeric and categorical features:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
aspect featurize compounds.csv \
|
|
146
|
+
--features mwt:log@log_mwt assay:hash@assay_hash pIC50@target \
|
|
147
|
+
--extras compound_id \
|
|
148
|
+
--output features.parquet
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The feature specification defines the transformations:
|
|
152
|
+
|
|
153
|
+
| Specification | Meaning |
|
|
154
|
+
|---|---|
|
|
155
|
+
| `mwt:log@log_mwt` | Apply natural logarithm to `mwt` |
|
|
156
|
+
| `assay:hash@assay_hash` | Hash the assay category into a fixed-length vector |
|
|
157
|
+
| `pIC50@target` | Copy `pIC50` into a feature named `target` |
|
|
158
|
+
| `--extras compound_id` | Explicitly retain the compound identifier |
|
|
159
|
+
|
|
160
|
+
By default, Aspect also retains original input columns.
|
|
161
|
+
|
|
162
|
+
### 2. Save a reproducible checkpoint
|
|
163
|
+
|
|
164
|
+
The same command can save a checkpoint alongside the exported table:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
aspect featurize compounds.csv \
|
|
168
|
+
--features mwt:log@log_mwt assay:hash@assay_hash \
|
|
169
|
+
--checkpoint features.as \
|
|
170
|
+
--output features.parquet
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The checkpoint records the feature specification, data source, and information needed to reconstruct the transformed dataset.
|
|
174
|
+
|
|
175
|
+
### 3. Restore and export
|
|
176
|
+
|
|
177
|
+
Reconstruct the transformed dataset from its checkpoint:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
aspect write features.as \
|
|
181
|
+
--output restored.parquet
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Export it in another format:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
aspect write features.as \
|
|
188
|
+
--output restored.csv.gz
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### 4. Python API
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
from aspect.data import DataPipeline
|
|
195
|
+
|
|
196
|
+
data = {
|
|
197
|
+
"compound_id": ["cmpd-1", "cmpd-2", "cmpd-3"],
|
|
198
|
+
"assay": ["MIC", "MIC", "IC50"],
|
|
199
|
+
"mwt": [46.07, 60.10, 78.11],
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
pipe = DataPipeline(
|
|
203
|
+
column_transforms={
|
|
204
|
+
"log_mwt": ("mwt", "log"),
|
|
205
|
+
"assay_hash": (
|
|
206
|
+
"assay",
|
|
207
|
+
{"name": "hash", "kwargs": {"ndim": 8}},
|
|
208
|
+
),
|
|
209
|
+
},
|
|
210
|
+
columns_to_keep=["compound_id"],
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
resolved = pipe(data, drop_unused_columns=True)
|
|
214
|
+
|
|
215
|
+
# Access the underlying Hugging Face Dataset
|
|
216
|
+
features = resolved.data
|
|
217
|
+
|
|
218
|
+
print(features.column_names)
|
|
219
|
+
print(features[:2])
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The transformed dataset contains:
|
|
223
|
+
|
|
224
|
+
```text
|
|
225
|
+
['compound_id', 'log_mwt', 'assay_hash']
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
`log_mwt` contains a numeric feature with shape `(n, 1)`, while `assay_hash` contains an `(n, 8)` feature matrix.
|
|
229
|
+
|
|
230
|
+
Save and reload the pipeline:
|
|
231
|
+
|
|
232
|
+
```python
|
|
233
|
+
pipe.save("features.as")
|
|
234
|
+
|
|
235
|
+
restored = DataPipeline.load("features.as")
|
|
236
|
+
print(restored.data_out.data[:2])
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Installation
|
|
242
|
+
|
|
243
|
+
Aspect requires Python 3.11 or later.
|
|
244
|
+
|
|
245
|
+
### Basic installation
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
pip install aspect-data
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Optional dependencies
|
|
252
|
+
|
|
253
|
+
Install only the features you need:
|
|
254
|
+
|
|
255
|
+
| Extra | Functionality | Installation |
|
|
256
|
+
|---|---|---|
|
|
257
|
+
| `chem` | Molecular fingerprints and descriptors via Schemist | `pip install "aspect-data[chem]"` |
|
|
258
|
+
| `bio` | Taxonomic fingerprints via Vectome | `pip install "aspect-data[bio]"` |
|
|
259
|
+
| `torch` | PyTorch integration | `pip install "aspect-data[torch]"` |
|
|
260
|
+
| `chemprop` | Chemprop molecular features | `pip install "aspect-data[chemprop]"` |
|
|
261
|
+
| `deep` | Transformer-based embeddings | `pip install "aspect-data[deep]"` |
|
|
262
|
+
|
|
263
|
+
### Install from source
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
git clone https://github.com/scbirlab/aspect.git
|
|
267
|
+
cd aspect
|
|
268
|
+
pip install -e ".[dev]"
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Aspect depends on [Providence](https://github.com/scbirlab/providence) (`>=0.0.2`), which provides the common dataset-resolution and checkpointing infrastructure.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Command-line interface
|
|
276
|
+
|
|
277
|
+
Aspect provides three commands:
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
aspect serialize
|
|
281
|
+
aspect featurize
|
|
282
|
+
aspect write
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
View available arguments with:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
aspect --help
|
|
289
|
+
aspect featurize --help
|
|
290
|
+
aspect serialize --help
|
|
291
|
+
aspect write --help
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### `aspect serialize`
|
|
295
|
+
|
|
296
|
+
Create a reusable feature specification without processing a dataset:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
aspect serialize \
|
|
300
|
+
--features mwt:log@log_mwt assay:hash@assay_hash \
|
|
301
|
+
--extras compound_id \
|
|
302
|
+
--output feature-spec.as
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
The specification can then be applied to other datasets:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
aspect featurize new-compounds.csv \
|
|
309
|
+
--config feature-spec.as \
|
|
310
|
+
--output new-features.parquet
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### `aspect featurize`
|
|
314
|
+
|
|
315
|
+
Apply a feature specification or saved pipeline to a dataset.
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
aspect featurize compounds.csv \
|
|
319
|
+
--features mwt:log@log_mwt assay:hash@assay_hash \
|
|
320
|
+
--output features.parquet
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
A saved specification can be supplied with `--config`:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
aspect featurize compounds.csv \
|
|
327
|
+
--config feature-spec.as \
|
|
328
|
+
--output features.parquet
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
#### Checkpoint without exporting
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
aspect featurize compounds.csv \
|
|
335
|
+
--config feature-spec.as \
|
|
336
|
+
--checkpoint features.as
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
#### Save source and transformed data
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
aspect featurize compounds.csv \
|
|
343
|
+
--config feature-spec.as \
|
|
344
|
+
--checkpoint features.as \
|
|
345
|
+
--force-write-data
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
This requests materialisation of both source and transformed data inside the checkpoint, making it less dependent on the original dataset remaining available.
|
|
349
|
+
|
|
350
|
+
Without this option, Providence can retain immutable remote datasets by reference, avoiding unnecessary duplication. Local inputs are generally packaged by the current implementation.
|
|
351
|
+
|
|
352
|
+
#### Process a subset of rows
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
aspect featurize large-table.parquet \
|
|
356
|
+
--start 1000 \
|
|
357
|
+
--end 2000 \
|
|
358
|
+
--features mwt:log@log_mwt \
|
|
359
|
+
--checkpoint subset.as
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
`--start` is inclusive and `--end` is exclusive. The example selects rows 1000–1999.
|
|
363
|
+
|
|
364
|
+
#### Configure the cache
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
aspect featurize compounds.csv \
|
|
368
|
+
--features assay:hash@assay_hash \
|
|
369
|
+
--cache .cache \
|
|
370
|
+
--output features.parquet
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### `aspect write`
|
|
374
|
+
|
|
375
|
+
Export data from a saved Aspect checkpoint:
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
aspect write features.as --output features.csv
|
|
379
|
+
aspect write features.as --output features.csv.gz
|
|
380
|
+
aspect write features.as --output features.parquet
|
|
381
|
+
aspect write features.as --output features.hf
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
The checkpoint is loaded through `DataPipeline.load()` and the output is delegated to Providence.
|
|
385
|
+
|
|
386
|
+
If the checkpoint contains only a feature specification and no source dataset, there is no transformed table to export.
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Python API
|
|
391
|
+
|
|
392
|
+
The main class is `DataPipeline`.
|
|
393
|
+
|
|
394
|
+
```python
|
|
395
|
+
from aspect.data import DataPipeline
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
A pipeline maps input columns to named output features.
|
|
399
|
+
|
|
400
|
+
```python
|
|
401
|
+
pipe = DataPipeline({
|
|
402
|
+
"log_mwt": ("mwt", "log"),
|
|
403
|
+
"assay_hash": (
|
|
404
|
+
"assay",
|
|
405
|
+
{"name": "hash", "kwargs": {"ndim": 16}},
|
|
406
|
+
),
|
|
407
|
+
})
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Input data
|
|
411
|
+
|
|
412
|
+
Pipelines can be applied to Python mappings, Pandas DataFrames, Hugging Face datasets, local files, or Providence resolvers.
|
|
413
|
+
|
|
414
|
+
```python
|
|
415
|
+
# Dictionary
|
|
416
|
+
resolved = pipe({
|
|
417
|
+
"mwt": [46.07, 60.10],
|
|
418
|
+
"assay": ["MIC", "IC50"],
|
|
419
|
+
})
|
|
420
|
+
|
|
421
|
+
# Pandas DataFrame
|
|
422
|
+
resolved = pipe(df)
|
|
423
|
+
|
|
424
|
+
# Local file
|
|
425
|
+
resolved = pipe("compounds.csv")
|
|
426
|
+
|
|
427
|
+
# Hugging Face Hub dataset
|
|
428
|
+
resolved = pipe(
|
|
429
|
+
"hf://datasets/scbirlab/fang-2023-biogen-adme~scaffold-split:train"
|
|
430
|
+
)
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Providence integration
|
|
434
|
+
|
|
435
|
+
Aspect uses Providence's `DataResolver` to manage source datasets and transformed results.
|
|
436
|
+
|
|
437
|
+
```python
|
|
438
|
+
from providence import DataResolver
|
|
439
|
+
from aspect.data import DataPipeline
|
|
440
|
+
|
|
441
|
+
source = DataResolver("compounds.csv")
|
|
442
|
+
|
|
443
|
+
pipe = DataPipeline({
|
|
444
|
+
"log_mwt": ("mwt", "log"),
|
|
445
|
+
})
|
|
446
|
+
|
|
447
|
+
result = pipe(source)
|
|
448
|
+
|
|
449
|
+
# Underlying datasets
|
|
450
|
+
input_ds = pipe.data_in.data
|
|
451
|
+
output_ds = result.data
|
|
452
|
+
|
|
453
|
+
# Source metadata
|
|
454
|
+
source_info = pipe.data_in.data_source
|
|
455
|
+
|
|
456
|
+
print(output_ds.column_names)
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
`DataPipeline.__call__()` returns a `DataResolver`, rather than a raw Hugging Face dataset.
|
|
460
|
+
|
|
461
|
+
The underlying dataset remains available through `.data`, and provenance is tracked through the resolver.
|
|
462
|
+
|
|
463
|
+
### Exporting results
|
|
464
|
+
|
|
465
|
+
```python
|
|
466
|
+
pipe.write_table("features.parquet")
|
|
467
|
+
pipe.write_table("features.csv.gz")
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
This delegates serialization to Providence.
|
|
471
|
+
|
|
472
|
+
### Selecting rows
|
|
473
|
+
|
|
474
|
+
For explicit row selection, create and slice the resolver before passing it to Aspect:
|
|
475
|
+
|
|
476
|
+
```python
|
|
477
|
+
source = DataResolver("compounds.csv")
|
|
478
|
+
source = source.select_rows(start=100, end=200)
|
|
479
|
+
|
|
480
|
+
result = pipe(source)
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### Reusing transformations
|
|
484
|
+
|
|
485
|
+
The same feature specification can be applied to multiple datasets:
|
|
486
|
+
|
|
487
|
+
```python
|
|
488
|
+
pipe = DataPipeline({
|
|
489
|
+
"log_mwt": ("mwt", "log"),
|
|
490
|
+
})
|
|
491
|
+
|
|
492
|
+
train = pipe("train.csv")
|
|
493
|
+
test = pipe("test.csv")
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Each call returns the corresponding transformed resolver. The pipeline's `data_in` and `data_out` attributes refer to the most recent call.
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## Feature specifications
|
|
501
|
+
|
|
502
|
+
Aspect supports both structured Python specifications and compact CLI strings.
|
|
503
|
+
|
|
504
|
+
### Python specifications
|
|
505
|
+
|
|
506
|
+
The basic format is:
|
|
507
|
+
|
|
508
|
+
```python
|
|
509
|
+
{
|
|
510
|
+
"output_column": ("input_column", "transform_name")
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Example:
|
|
515
|
+
|
|
516
|
+
```python
|
|
517
|
+
pipe = DataPipeline({
|
|
518
|
+
"log_mwt": ("mwt", "log"),
|
|
519
|
+
})
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### Parameterised transforms
|
|
523
|
+
|
|
524
|
+
Pass a dictionary containing the transform name and keyword arguments:
|
|
525
|
+
|
|
526
|
+
```python
|
|
527
|
+
pipe = DataPipeline({
|
|
528
|
+
"assay_hash": (
|
|
529
|
+
"assay",
|
|
530
|
+
{
|
|
531
|
+
"name": "hash",
|
|
532
|
+
"kwargs": {
|
|
533
|
+
"ndim": 32,
|
|
534
|
+
"seed": 123,
|
|
535
|
+
},
|
|
536
|
+
},
|
|
537
|
+
),
|
|
538
|
+
})
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
### Chained transforms
|
|
542
|
+
|
|
543
|
+
Pass a sequence of transformations:
|
|
544
|
+
|
|
545
|
+
```python
|
|
546
|
+
pipe = DataPipeline({
|
|
547
|
+
"scaled_log_mwt": (
|
|
548
|
+
"mwt",
|
|
549
|
+
[
|
|
550
|
+
"log",
|
|
551
|
+
{
|
|
552
|
+
"name": "scale",
|
|
553
|
+
"kwargs": {"factor": 0.1},
|
|
554
|
+
},
|
|
555
|
+
],
|
|
556
|
+
),
|
|
557
|
+
})
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
The `scale` transform in this example is a custom transform that must be registered first.
|
|
561
|
+
|
|
562
|
+
Chains execute in the supplied order. Each transform must accept the representation produced by the preceding transform.
|
|
563
|
+
|
|
564
|
+
### CLI specifications
|
|
565
|
+
|
|
566
|
+
The CLI format is:
|
|
567
|
+
|
|
568
|
+
```text
|
|
569
|
+
input_column:transform@output_column
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
| Syntax | Behaviour |
|
|
573
|
+
|---|---|
|
|
574
|
+
| `column` | Retain an input column |
|
|
575
|
+
| `column@new_name` | Identity transformation with a new name |
|
|
576
|
+
| `column:transform` | Apply a transform and automatically name the output |
|
|
577
|
+
| `column:transform@new_name` | Apply a transform with an explicit output name |
|
|
578
|
+
| `column:t1:t2@new_name` | Chain transformations |
|
|
579
|
+
| `column:transform(arg=value)@name` | Pass simple transform arguments |
|
|
580
|
+
|
|
581
|
+
Example:
|
|
582
|
+
|
|
583
|
+
```bash
|
|
584
|
+
aspect featurize compounds.csv \
|
|
585
|
+
--features \
|
|
586
|
+
mwt:log@log_mwt \
|
|
587
|
+
assay:hash(ndim=32)@assay_hash \
|
|
588
|
+
pIC50@target \
|
|
589
|
+
--output features.parquet
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
Simple integers, floats, and booleans are parsed automatically. For complex or nested parameters, use the Python API.
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## Available transforms
|
|
597
|
+
|
|
598
|
+
### Base transforms
|
|
599
|
+
|
|
600
|
+
Available with the standard installation:
|
|
601
|
+
|
|
602
|
+
| Transform | Input | Output |
|
|
603
|
+
|---|---|---|
|
|
604
|
+
| `identity` | Any supported column | Identity representation |
|
|
605
|
+
| `log` | Numeric | Natural logarithm |
|
|
606
|
+
| `hash` | Categorical/string | Deterministic fixed-length vector |
|
|
607
|
+
| `one-hot` | Categorical | One-hot vector |
|
|
608
|
+
|
|
609
|
+
Example:
|
|
610
|
+
|
|
611
|
+
```python
|
|
612
|
+
pipe = DataPipeline({
|
|
613
|
+
"log_mwt": ("mwt", "log"),
|
|
614
|
+
"assay_hash": (
|
|
615
|
+
"assay",
|
|
616
|
+
{"name": "hash", "kwargs": {"ndim": 16}},
|
|
617
|
+
),
|
|
618
|
+
"assay_onehot": (
|
|
619
|
+
"assay",
|
|
620
|
+
{
|
|
621
|
+
"name": "one-hot",
|
|
622
|
+
"kwargs": {"categories": ["MIC", "IC50"]},
|
|
623
|
+
},
|
|
624
|
+
),
|
|
625
|
+
})
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### Chemistry transforms
|
|
629
|
+
|
|
630
|
+
Install with:
|
|
631
|
+
|
|
632
|
+
```bash
|
|
633
|
+
pip install "aspect-data[chem]"
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
| Transform | Input | Output |
|
|
637
|
+
|---|---|---|
|
|
638
|
+
| `morgan-fingerprint` | SMILES | Molecular fingerprint |
|
|
639
|
+
| `descriptors-2d` | SMILES | 2D molecular descriptors |
|
|
640
|
+
| `descriptors-3d` | SMILES | 3D molecular descriptors |
|
|
641
|
+
|
|
642
|
+
Example:
|
|
643
|
+
|
|
644
|
+
```python
|
|
645
|
+
data = {
|
|
646
|
+
"compound_id": ["ethanol", "ethylamine", "benzene"],
|
|
647
|
+
"smiles": ["CCO", "CCN", "c1ccccc1"],
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
pipe = DataPipeline(
|
|
651
|
+
{
|
|
652
|
+
"morgan": ("smiles", "morgan-fingerprint"),
|
|
653
|
+
"desc2d": ("smiles", "descriptors-2d"),
|
|
654
|
+
},
|
|
655
|
+
columns_to_keep=["compound_id"],
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
features = pipe(data, drop_unused_columns=True).data
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### Taxonomic transforms
|
|
662
|
+
|
|
663
|
+
Install with:
|
|
664
|
+
|
|
665
|
+
```bash
|
|
666
|
+
pip install "aspect-data[bio]"
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
The `vectome-fingerprint` transform encodes species names or taxonomic identifiers as fixed-length taxonomic representations.
|
|
670
|
+
|
|
671
|
+
```python
|
|
672
|
+
data = {
|
|
673
|
+
"species": [
|
|
674
|
+
"Mycobacterium tuberculosis",
|
|
675
|
+
"Escherichia coli",
|
|
676
|
+
"Staphylococcus aureus",
|
|
677
|
+
],
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
pipe = DataPipeline({
|
|
681
|
+
"species_fp": (
|
|
682
|
+
"species",
|
|
683
|
+
{
|
|
684
|
+
"name": "vectome-fingerprint",
|
|
685
|
+
"kwargs": {"ndim": 128},
|
|
686
|
+
},
|
|
687
|
+
),
|
|
688
|
+
})
|
|
689
|
+
|
|
690
|
+
features = pipe(data).data
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
### Deep-learning transforms
|
|
694
|
+
|
|
695
|
+
Install with:
|
|
696
|
+
|
|
697
|
+
```bash
|
|
698
|
+
pip install "aspect-data[deep]"
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
The `hf-bart` transform supports transformer-derived text embeddings.
|
|
702
|
+
|
|
703
|
+
```python
|
|
704
|
+
data = {
|
|
705
|
+
"description": [
|
|
706
|
+
"cell wall inhibitor",
|
|
707
|
+
"protein synthesis inhibitor",
|
|
708
|
+
"DNA gyrase inhibitor",
|
|
709
|
+
],
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
pipe = DataPipeline({
|
|
713
|
+
"text_embedding": (
|
|
714
|
+
"description",
|
|
715
|
+
{
|
|
716
|
+
"name": "hf-bart",
|
|
717
|
+
"kwargs": {
|
|
718
|
+
"ref": "facebook/bart-base",
|
|
719
|
+
"aggregator": ["mean", "max"],
|
|
720
|
+
},
|
|
721
|
+
},
|
|
722
|
+
),
|
|
723
|
+
})
|
|
724
|
+
|
|
725
|
+
features = pipe(data).data
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
Model weights may be downloaded on first use.
|
|
729
|
+
|
|
730
|
+
### Chemprop transforms
|
|
731
|
+
|
|
732
|
+
Install with:
|
|
733
|
+
|
|
734
|
+
```bash
|
|
735
|
+
pip install "aspect-data[chemprop]"
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
The `chemprop-mol` transform prepares molecular datapoints for Chemprop-style graph models.
|
|
739
|
+
|
|
740
|
+
Molecular graphs generally require model-specific batching. Aspect separates dataset storage from runtime collation so graph representations can be reconstructed when needed.
|
|
741
|
+
|
|
742
|
+
---
|
|
743
|
+
|
|
744
|
+
## Saving and loading pipelines
|
|
745
|
+
|
|
746
|
+
Aspect supports reusable feature specifications and provenance-aware dataset checkpoints.
|
|
747
|
+
|
|
748
|
+
### Save a feature specification
|
|
749
|
+
|
|
750
|
+
Create a pipeline without applying it to any dataset:
|
|
751
|
+
|
|
752
|
+
```python
|
|
753
|
+
pipe = DataPipeline({
|
|
754
|
+
"log_mwt": ("mwt", "log"),
|
|
755
|
+
"assay_hash": (
|
|
756
|
+
"assay",
|
|
757
|
+
{"name": "hash", "kwargs": {"ndim": 16}},
|
|
758
|
+
),
|
|
759
|
+
})
|
|
760
|
+
|
|
761
|
+
pipe.save("feature-spec.as")
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
Restore and apply it later:
|
|
765
|
+
|
|
766
|
+
```python
|
|
767
|
+
from aspect.data import DataPipeline
|
|
768
|
+
|
|
769
|
+
pipe = DataPipeline.load("feature-spec.as")
|
|
770
|
+
|
|
771
|
+
result = pipe({
|
|
772
|
+
"mwt": [46.07, 60.10],
|
|
773
|
+
"assay": ["MIC", "IC50"],
|
|
774
|
+
})
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
### Checkpoint a transformed dataset
|
|
778
|
+
|
|
779
|
+
```python
|
|
780
|
+
pipe = DataPipeline({
|
|
781
|
+
"log_mwt": ("mwt", "log"),
|
|
782
|
+
})
|
|
783
|
+
|
|
784
|
+
result = pipe("compounds.csv")
|
|
785
|
+
pipe.save("features.as")
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
The checkpoint records the pipeline configuration and a Providence checkpoint describing the input dataset.
|
|
789
|
+
|
|
790
|
+
Load it again:
|
|
791
|
+
|
|
792
|
+
```python
|
|
793
|
+
restored = DataPipeline.load("features.as")
|
|
794
|
+
|
|
795
|
+
features = restored.data_out.data
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
By default, when transformed data has not been explicitly saved, loading reconstructs it by applying the feature pipeline to the restored source dataset.
|
|
799
|
+
|
|
800
|
+
### Materialise transformed data
|
|
801
|
+
|
|
802
|
+
```python
|
|
803
|
+
pipe.save(
|
|
804
|
+
"features.as",
|
|
805
|
+
save_transformed=True,
|
|
806
|
+
)
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
This stores a transformed-data checkpoint alongside the source checkpoint.
|
|
810
|
+
|
|
811
|
+
### Package source data
|
|
812
|
+
|
|
813
|
+
```python
|
|
814
|
+
pipe.save(
|
|
815
|
+
"features.as",
|
|
816
|
+
save_source_data=True,
|
|
817
|
+
save_transformed=True,
|
|
818
|
+
)
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
This requests packaging of the input data and transformed data.
|
|
822
|
+
|
|
823
|
+
For remote datasets with immutable revisions, Providence can instead retain source references, allowing checkpoints to be substantially smaller.
|
|
824
|
+
|
|
825
|
+
Local sources are normally materialised to preserve reproducibility.
|
|
826
|
+
|
|
827
|
+
### Load without applying transformations
|
|
828
|
+
|
|
829
|
+
```python
|
|
830
|
+
pipe = DataPipeline.load(
|
|
831
|
+
"features.as",
|
|
832
|
+
skip_call=True,
|
|
833
|
+
)
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
This restores the specification and available checkpoint artefacts without automatically running the transformation pipeline.
|
|
837
|
+
|
|
838
|
+
### Checkpoint layout
|
|
839
|
+
|
|
840
|
+
A checkpoint may contain:
|
|
841
|
+
|
|
842
|
+
```text
|
|
843
|
+
features.as/
|
|
844
|
+
├── config.json
|
|
845
|
+
├── data.pv/
|
|
846
|
+
└── transformed.pv/
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
`config.json` contains the pipeline specification and checkpoint metadata.
|
|
850
|
+
|
|
851
|
+
`data.pv` contains the Providence source checkpoint.
|
|
852
|
+
|
|
853
|
+
`transformed.pv` is included when transformed data is explicitly checkpointed.
|
|
854
|
+
|
|
855
|
+
The contents of Providence checkpoints depend on whether datasets are retained by reference or materialised.
|
|
856
|
+
|
|
857
|
+
### Compatibility
|
|
858
|
+
|
|
859
|
+
The legacy methods `save_checkpoint()` and `load_checkpoint()` remain available as compatibility aliases, but new code should use `save()` and `load()`.
|
|
860
|
+
|
|
861
|
+
---
|
|
862
|
+
|
|
863
|
+
## Supported input and output formats
|
|
864
|
+
|
|
865
|
+
### Input types
|
|
866
|
+
|
|
867
|
+
Aspect accepts the input types supported by Providence, including:
|
|
868
|
+
|
|
869
|
+
| Input | Example |
|
|
870
|
+
|---|---|
|
|
871
|
+
| Python mapping | `{"smiles": ["CCO", "CCN"]}` |
|
|
872
|
+
| Pandas DataFrame | `pipe(df)` |
|
|
873
|
+
| Hugging Face Dataset | `pipe(dataset)` |
|
|
874
|
+
| Hugging Face IterableDataset | `pipe(iterable_dataset)` |
|
|
875
|
+
| Local file | `pipe("data.csv")` |
|
|
876
|
+
| Hugging Face dataset reference | `pipe("hf://datasets/org/repo~config:split")` |
|
|
877
|
+
| Providence DataResolver | `pipe(resolved)` |
|
|
878
|
+
|
|
879
|
+
### Local files
|
|
880
|
+
|
|
881
|
+
Commonly supported formats include:
|
|
882
|
+
|
|
883
|
+
- CSV: `.csv`, `.csv.gz`
|
|
884
|
+
- Tab-separated: `.tsv`, `.tsv.gz`, `.txt`, `.txt.gz`
|
|
885
|
+
- JSON: `.json`
|
|
886
|
+
- Parquet: `.parquet`
|
|
887
|
+
- Arrow: `.arrow`
|
|
888
|
+
- XML: `.xml`
|
|
889
|
+
- Saved Hugging Face datasets: `.hf`
|
|
890
|
+
|
|
891
|
+
### Output formats
|
|
892
|
+
|
|
893
|
+
The CLI and `write_table()` use Providence to select an output format from the filename.
|
|
894
|
+
|
|
895
|
+
| Extension | Format |
|
|
896
|
+
|---|---|
|
|
897
|
+
| `.csv` | CSV |
|
|
898
|
+
| `.csv.gz` | Gzip-compressed CSV |
|
|
899
|
+
| `.tsv`, `.txt` | Tab-separated text |
|
|
900
|
+
| `.tsv.gz`, `.txt.gz` | Gzip-compressed tab-separated text |
|
|
901
|
+
| `.json` | JSON |
|
|
902
|
+
| `.parquet` | Parquet |
|
|
903
|
+
| `.hf` | Hugging Face dataset directory |
|
|
904
|
+
| Unrecognised | Hugging Face dataset directory with `.hf` appended |
|
|
905
|
+
|
|
906
|
+
### Hugging Face Hub references
|
|
907
|
+
|
|
908
|
+
Providence supports versioned dataset references:
|
|
909
|
+
|
|
910
|
+
```text
|
|
911
|
+
hf://datasets/<owner>/<repo>~<config>:<split>@<revision>
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
For example:
|
|
915
|
+
|
|
916
|
+
```text
|
|
917
|
+
hf://datasets/scbirlab/fang-2023-biogen-adme~scaffold-split:train
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
The revision, configuration, and split are optional where supported by the resolver.
|
|
921
|
+
|
|
922
|
+
Pinning a dataset to an immutable commit revision improves reproducibility.
|
|
923
|
+
|
|
924
|
+
---
|
|
925
|
+
|
|
926
|
+
## Working with output columns
|
|
927
|
+
|
|
928
|
+
By default, Aspect retains original columns and adds transformed features.
|
|
929
|
+
|
|
930
|
+
```python
|
|
931
|
+
out = pipe(data)
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
To retain only transformed features and explicitly selected metadata:
|
|
935
|
+
|
|
936
|
+
```python
|
|
937
|
+
pipe = DataPipeline(
|
|
938
|
+
{
|
|
939
|
+
"log_mwt": ("mwt", "log"),
|
|
940
|
+
"assay_hash": ("assay", "hash"),
|
|
941
|
+
},
|
|
942
|
+
columns_to_keep=["compound_id"],
|
|
943
|
+
)
|
|
944
|
+
|
|
945
|
+
out = pipe(
|
|
946
|
+
data,
|
|
947
|
+
drop_unused_columns=True,
|
|
948
|
+
)
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
Extra columns can also be specified at call time:
|
|
952
|
+
|
|
953
|
+
```python
|
|
954
|
+
out = pipe(
|
|
955
|
+
data,
|
|
956
|
+
drop_unused_columns=True,
|
|
957
|
+
keep_extra_columns=["compound_id", "target"],
|
|
958
|
+
)
|
|
959
|
+
```
|
|
960
|
+
|
|
961
|
+
Access the underlying output dataset using:
|
|
962
|
+
|
|
963
|
+
```python
|
|
964
|
+
dataset = out.data
|
|
965
|
+
print(dataset.features)
|
|
966
|
+
print(dataset.column_names)
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
---
|
|
970
|
+
|
|
971
|
+
## Custom transforms
|
|
972
|
+
|
|
973
|
+
Custom transforms can be registered through Aspect's transform registry.
|
|
974
|
+
|
|
975
|
+
A transform factory receives configuration arguments and returns a callable that operates on data batches.
|
|
976
|
+
|
|
977
|
+
```python
|
|
978
|
+
import numpy as np
|
|
979
|
+
|
|
980
|
+
from aspect.data import DataPipeline
|
|
981
|
+
from aspect.transform.registry import register_function
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
@register_function("square")
|
|
985
|
+
def Square():
|
|
986
|
+
def _square(data, input_column):
|
|
987
|
+
x = np.asarray(data[input_column], dtype=float)
|
|
988
|
+
return x ** 2
|
|
989
|
+
|
|
990
|
+
return _square
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
pipe = DataPipeline({
|
|
994
|
+
"mwt_squared": ("mwt", "square"),
|
|
995
|
+
})
|
|
996
|
+
|
|
997
|
+
out = pipe({
|
|
998
|
+
"mwt": [46.07, 60.10, 78.11],
|
|
999
|
+
}).data
|
|
1000
|
+
```
|
|
1001
|
+
|
|
1002
|
+
### Parameterised transforms
|
|
1003
|
+
|
|
1004
|
+
```python
|
|
1005
|
+
@register_function("scale")
|
|
1006
|
+
def Scale(factor=1.0):
|
|
1007
|
+
def _scale(data, input_column):
|
|
1008
|
+
x = np.asarray(data[input_column], dtype=float)
|
|
1009
|
+
return x * factor
|
|
1010
|
+
|
|
1011
|
+
return _scale
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
pipe = DataPipeline({
|
|
1015
|
+
"scaled_mwt": (
|
|
1016
|
+
"mwt",
|
|
1017
|
+
{"name": "scale", "kwargs": {"factor": 0.001}},
|
|
1018
|
+
),
|
|
1019
|
+
})
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
Custom transforms must be registered in the Python process before loading pipelines that reference them.
|
|
1023
|
+
|
|
1024
|
+
---
|
|
1025
|
+
|
|
1026
|
+
## Model integration
|
|
1027
|
+
|
|
1028
|
+
Aspect separates stored feature representations from model-specific runtime inputs.
|
|
1029
|
+
|
|
1030
|
+
The output dataset may contain numeric arrays, chemical fingerprints, taxonomic encodings, or other Arrow-compatible values.
|
|
1031
|
+
|
|
1032
|
+
For simple numerical models, extract the dataset:
|
|
1033
|
+
|
|
1034
|
+
```python
|
|
1035
|
+
features = pipe(data).data
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
For PyTorch models, use the built-in DataLoader integration:
|
|
1039
|
+
|
|
1040
|
+
```python
|
|
1041
|
+
loader = pipe.dataloader(
|
|
1042
|
+
batch_size=32,
|
|
1043
|
+
shuffle=True,
|
|
1044
|
+
)
|
|
1045
|
+
|
|
1046
|
+
for batch in loader:
|
|
1047
|
+
# Batched, collated features
|
|
1048
|
+
pass
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
This requires the `torch` extra.
|
|
1052
|
+
|
|
1053
|
+
Transforms requiring specialised runtime representations can provide collators. These are applied when constructing model batches, allowing features such as molecular graphs to be stored independently from the framework-specific objects consumed by a model.
|
|
1054
|
+
|
|
1055
|
+
Custom collators can be provided through the `collators` argument:
|
|
1056
|
+
|
|
1057
|
+
```python
|
|
1058
|
+
loader = pipe.dataloader(
|
|
1059
|
+
batch_size=32,
|
|
1060
|
+
collators={
|
|
1061
|
+
"custom_feature": custom_collator,
|
|
1062
|
+
},
|
|
1063
|
+
)
|
|
1064
|
+
```
|
|
1065
|
+
|
|
1066
|
+
### Mixed molecular and biological features
|
|
1067
|
+
|
|
1068
|
+
Aspect can combine multiple representations in one dataset:
|
|
1069
|
+
|
|
1070
|
+
```python
|
|
1071
|
+
data = {
|
|
1072
|
+
"compound_id": ["cmpd-1", "cmpd-2", "cmpd-3"],
|
|
1073
|
+
"smiles": ["CCO", "CCN", "c1ccccc1"],
|
|
1074
|
+
"assay": ["solubility", "clearance", "microsome"],
|
|
1075
|
+
"species": [
|
|
1076
|
+
"Escherichia coli",
|
|
1077
|
+
"Mycobacterium tuberculosis",
|
|
1078
|
+
"Staphylococcus aureus",
|
|
1079
|
+
],
|
|
1080
|
+
"mwt": [46.07, 45.08, 78.11],
|
|
1081
|
+
"label": [0.1, 0.4, 0.8],
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
pipe = DataPipeline(
|
|
1085
|
+
{
|
|
1086
|
+
"morgan": ("smiles", "morgan-fingerprint"),
|
|
1087
|
+
"desc2d": ("smiles", "descriptors-2d"),
|
|
1088
|
+
"assay_hash": (
|
|
1089
|
+
"assay",
|
|
1090
|
+
{"name": "hash", "kwargs": {"ndim": 32}},
|
|
1091
|
+
),
|
|
1092
|
+
"species_fp": (
|
|
1093
|
+
"species",
|
|
1094
|
+
{"name": "vectome-fingerprint", "kwargs": {"ndim": 64}},
|
|
1095
|
+
),
|
|
1096
|
+
"log_mwt": ("mwt", "log"),
|
|
1097
|
+
"y": ("label", "identity"),
|
|
1098
|
+
},
|
|
1099
|
+
columns_to_keep=["compound_id"],
|
|
1100
|
+
)
|
|
1101
|
+
|
|
1102
|
+
features = pipe(
|
|
1103
|
+
data,
|
|
1104
|
+
drop_unused_columns=True,
|
|
1105
|
+
).data
|
|
1106
|
+
```
|
|
1107
|
+
|
|
1108
|
+
This requires the chemistry and taxonomy extras.
|
|
1109
|
+
|
|
1110
|
+
Downstream models can independently consume molecular fingerprints, descriptors, categorical features, and taxonomic encodings, or combine suitable dense features into a common representation.
|
|
1111
|
+
|
|
1112
|
+
---
|
|
1113
|
+
|
|
1114
|
+
## Development
|
|
1115
|
+
|
|
1116
|
+
Install the development dependencies:
|
|
1117
|
+
|
|
1118
|
+
```bash
|
|
1119
|
+
pip install -e ".[dev]"
|
|
1120
|
+
```
|
|
1121
|
+
|
|
1122
|
+
Run the test suite:
|
|
1123
|
+
|
|
1124
|
+
```bash
|
|
1125
|
+
pytest
|
|
1126
|
+
```
|
|
1127
|
+
|
|
1128
|
+
Run module doctests:
|
|
1129
|
+
|
|
1130
|
+
```bash
|
|
1131
|
+
pytest aspect --doctest-modules
|
|
1132
|
+
```
|
|
1133
|
+
|
|
1134
|
+
Run the CLI integration tests:
|
|
1135
|
+
|
|
1136
|
+
```bash
|
|
1137
|
+
bash test/scripts/run-tests.sh
|
|
1138
|
+
```
|
|
1139
|
+
|
|
1140
|
+
Aspect maintains separate GitHub Actions workflows for Python tests and CLI smoke tests.
|
|
1141
|
+
|
|
1142
|
+
## Related packages
|
|
1143
|
+
|
|
1144
|
+
Aspect is part of a small ecosystem for reproducible molecular machine-learning workflows:
|
|
1145
|
+
|
|
1146
|
+
- [Providence](https://github.com/scbirlab/providence) — Dataset loading, source provenance, and checkpointing.
|
|
1147
|
+
- [Eluent](https://github.com/scbirlab/eluent) — Chemistry-aware grouping, splitting, and cross-validation.
|
|
1148
|
+
- [Schemist](https://github.com/scbirlab/schemist) — Molecular featurisation and cheminformatics.
|
|
1149
|
+
- [Vectome](https://github.com/scbirlab/vectome) — Taxonomic and biological representations.
|
|
1150
|
+
|
|
1151
|
+
The packages can be used independently or composed into reproducible workflows from source data to model-ready features and evaluation splits.
|
|
1152
|
+
|
|
1153
|
+
---
|
|
1154
|
+
|
|
1155
|
+
## Issues and documentation
|
|
1156
|
+
|
|
1157
|
+
Bug reports, feature requests, and contributions are welcome through the [GitHub issue tracker](https://github.com/scbirlab/aspect/issues).
|
|
1158
|
+
|
|
1159
|
+
Documentation: [aspect.readthedocs.org](https://aspect.readthedocs.org)
|
|
1160
|
+
|
|
1161
|
+
Source code: [github.com/scbirlab/aspect](https://github.com/scbirlab/aspect)
|
|
1162
|
+
|
|
1163
|
+
License: MIT.
|