Repository: EBjerrum/scikit-mol
Branch: main
Commit: 119cb8c00bb4
Files: 128
Total size: 3.7 MB
Directory structure:
gitextract_o126_axo/
├── .github/
│ ├── CODEOWNERS
│ └── workflows/
│ ├── code_quality.yaml
│ ├── publish.yaml
│ ├── pytest.yaml
│ └── welcome.yaml
├── .gitignore
├── .pre-commit-config.yaml
├── .readthedocs.yaml
├── .vscode/
│ ├── extensions.json
│ └── settings.json
├── CITATION.bib
├── CONTRIBUTING.md
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.md
├── docs/
│ ├── api/
│ │ ├── fingerprints.base.md
│ │ ├── scikit_mol.applicability.md
│ │ ├── scikit_mol.conversions.md
│ │ ├── scikit_mol.core.md
│ │ ├── scikit_mol.descriptors.md
│ │ ├── scikit_mol.fingerprints.md
│ │ ├── scikit_mol.parallel.md
│ │ ├── scikit_mol.plotting.md
│ │ ├── scikit_mol.safeinference.md
│ │ └── scikit_mol.standardizer.md
│ ├── assets/
│ │ ├── css/
│ │ │ └── tweak-width.css
│ │ └── js/
│ │ └── readthedocs.js
│ ├── contributing.md
│ ├── index.md
│ ├── notebooks/
│ │ ├── 01_basic_usage.ipynb
│ │ ├── 02_descriptor_transformer.ipynb
│ │ ├── 03_example_pipeline.ipynb
│ │ ├── 04_standardizer.ipynb
│ │ ├── 05_smiles_sanitization.ipynb
│ │ ├── 06_hyperparameter_tuning.ipynb
│ │ ├── 07_parallel_transforms.ipynb
│ │ ├── 08_external_library_skopt.ipynb
│ │ ├── 09_Combinatorial_Method_Usage_with_FingerPrint_Transformers.ipynb
│ │ ├── 10_pipeline_pandas_output.ipynb
│ │ ├── 11_safe_inference.ipynb
│ │ ├── 12_custom_fingerprint_transformer.ipynb
│ │ ├── 13_applicability_domain.ipynb
│ │ ├── README.md
│ │ ├── pair_notebook.sh
│ │ ├── run_notebooks.sh
│ │ ├── scripts/
│ │ │ ├── 01_basic_usage.py
│ │ │ ├── 02_descriptor_transformer.py
│ │ │ ├── 03_example_pipeline.py
│ │ │ ├── 04_standardizer.py
│ │ │ ├── 05_smiles_sanitization.py
│ │ │ ├── 06_hyperparameter_tuning.py
│ │ │ ├── 07_parallel_transforms.py
│ │ │ ├── 08_external_library_skopt.py
│ │ │ ├── 09_Combinatorial_Method_Usage_with_FingerPrint_Transformers.py
│ │ │ ├── 10_pipeline_pandas_output.py
│ │ │ ├── 11_safe_inference.py
│ │ │ ├── 12_custom_fingerprint_transformer.py
│ │ │ └── 13_applicability_domain.py
│ │ └── sync_notebooks.sh
│ └── overrides/
│ └── main.html
├── mkdocs.yml
├── pyproject.toml
├── resources/
│ └── logo/
│ ├── ScikitMol_Logo.ai
│ └── ScikitMol_Logo_Hybrid.ai
├── ruff.toml
├── scikit_mol/
│ ├── __init__.py
│ ├── _constants.py
│ ├── applicability/
│ │ ├── LICENSE.MIT
│ │ ├── README.md
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── bounding_box.py
│ │ ├── convex_hull.py
│ │ ├── hotelling.py
│ │ ├── isolation_forest.py
│ │ ├── kernel_density.py
│ │ ├── knn.py
│ │ ├── leverage.py
│ │ ├── local_outlier.py
│ │ ├── mahalanobis.py
│ │ ├── standardization.py
│ │ └── topkat.py
│ ├── conversions.py
│ ├── core.py
│ ├── descriptors.py
│ ├── fingerprints/
│ │ ├── __init__.py
│ │ ├── atompair.py
│ │ ├── avalon.py
│ │ ├── baseclasses.py
│ │ ├── maccs.py
│ │ ├── minhash.py
│ │ ├── morgan.py
│ │ ├── rdkitfp.py
│ │ └── topologicaltorsion.py
│ ├── parallel.py
│ ├── plotting.py
│ ├── safeinference.py
│ ├── standardizer.py
│ └── utilities.py
├── setup.cfg
├── tests/
│ ├── __init__.py
│ ├── applicability/
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── test_base.py
│ │ ├── test_bounding_box.py
│ │ ├── test_convex_hull.py
│ │ ├── test_hotelling.py
│ │ ├── test_isolation_forest.py
│ │ ├── test_kernel_density.py
│ │ ├── test_knn.py
│ │ ├── test_leverage.py
│ │ ├── test_local_outlier.py
│ │ ├── test_mahalanobis.py
│ │ ├── test_standardization.py
│ │ └── test_topkat.py
│ ├── conftest.py
│ ├── fixtures.py
│ ├── test_desctransformer.py
│ ├── test_fptransformers.py
│ ├── test_fptransformersgenerator.py
│ ├── test_parameter_types.py
│ ├── test_safeinferencemode.py
│ ├── test_sanitizer.py
│ ├── test_scikit_mol.py
│ ├── test_smilestomol.py
│ └── test_transformers.py
└── uv.toml
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/CODEOWNERS
================================================
* @EBjerrum
scikit_mol/parallel.py @asiomchen
scikit_mol/plotting.py @asiomchen
================================================
FILE: .github/workflows/code_quality.yaml
================================================
name: Code Quality Checks
on: [ push, pull_request ]
jobs:
ruff-checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check code formatting
uses: astral-sh/ruff-action@v3
with:
version: 0.8.6
args: "format --check"
src: "./scikit_mol"
- name: Check code style
uses: astral-sh/ruff-action@v3
with:
version: 0.8.6
args: "check"
src: "./scikit_mol"
================================================
FILE: .github/workflows/publish.yaml
================================================
name: Publish Python🐍 distribution📦 with uv🌈
# after releasing a new version, build the distribution and uploads signed artifacts to GitHub Release
on:
workflow_call:
inputs:
python-version:
type: string
description: "Python version to use"
required: true
default: "3.9"
is-draft:
type: boolean
description: "Is this a draft release?"
required: false
default: false
dist-artifact-name:
type: string
description: "Name of the created distribution artifact"
required: false
default: "python-package-distributions"
jobs:
build-and-publish:
name: Build distribution📦
runs-on: ubuntu-latest
permissions:
contents: write #
id-token: write # IMPORTANT: mandatory for sigstore
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Python🐍
uses: astral-sh/setup-uv@v5
with:
python-version: ${{ inputs.python-version }}
- name: Build a binary wheel and a source tarball
run: uv build
- name: Store the distribution packages
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.dist-artifact-name }}
path: dist/
github-release:
name: >-
Sign the distribution📦 with Sigstore
and upload them to GitHub Release
needs:
- build-and-publish
runs-on: ubuntu-latest
permissions:
contents: write # IMPORTANT: mandatory for making GitHub Releases
id-token: write # IMPORTANT: mandatory for sigstore
steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: ${{ inputs.dist-artifact-name }}
path: dist/
- name: Sign the dists with Sigstore🔏
uses: sigstore/gh-action-sigstore-python@v3.0.0
with:
inputs: >-
./dist/*.tar.gz
./dist/*.whl
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
gh release create
"$GITHUB_REF_NAME"
--repo "$GITHUB_REPOSITORY"
--generate-notes ${{ inputs.is-draft && '--draft' || '' }}
- name: Upload artifact signatures to GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
gh release upload
"$GITHUB_REF_NAME" dist/**
--repo "$GITHUB_REPOSITORY"
================================================
FILE: .github/workflows/pytest.yaml
================================================
name: scikit_mol ci
on:
push:
branches: [main]
tags: ['v*']
pull_request:
branches: [main]
# cancel previously running tests if new commits are made
# https://docs.github.com/en/actions/examples/using-concurrency-expressions-and-a-test-matrix
concurrency:
group: actions-id-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
# run pytests for scikit_mol
tests:
name: pytest ${{ matrix.os }}::py${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
strategy:
max-parallel: 6
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10"]
include:
# test python version compatibility on linux only
- os: ubuntu-latest
python-version: 3.13
- os: ubuntu-latest
python-version: 3.12
- os: ubuntu-latest
python-version: 3.11
- os: ubuntu-latest
python-version: 3.10
- os: ubuntu-latest
python-version: 3.9
steps:
- name: Checkout scikit_mol
uses: actions/checkout@v4
- name: Install uv and set the python version
uses: astral-sh/setup-uv@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install scikit_mol
run: uv sync --dev
- name: Cache tests/data
uses: actions/cache@v4
with:
path: tests/data
key: ${{ runner.os }}-${{ hashFiles('tests/conftest.py') }}
- name: Run Tests
run: uv run pytest --cov=./scikit_mol .
build-and-create-signed-release:
name: Build distribution📦 & create Github Release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
needs: tests
uses: ./.github/workflows/publish.yaml
with:
python-version: "3.9"
is-draft: true
publish:
name: Publish to PyPI
needs: build-and-create-signed-release
runs-on: ubuntu-latest
# will be enabled in the future
# environment:
# name: pypi
# url: https://pypi.org/p/scikit-mol
permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing
steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
================================================
FILE: .github/workflows/welcome.yaml
================================================
name: Welcome WorkFlow
on:
issues:
types: [opened]
pull_request_target:
types: [opened]
jobs:
build:
name: 👋 Welcome
permissions: write-all
runs-on: ubuntu-latest
steps:
- uses: actions/first-interaction@v1.3.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-message: "🎉 Welcome to scikit-mol! 🧪✨ Thank you for opening your first issue! 🚀 Your feedback helps improve the project and makes a difference. 💡 If you have any questions or need guidance, don't hesitate to ask. We're here to help! 🤝"
pr-message: "🎉 Welcome to scikit-mol! 🧪✨ Thank you for submitting your first pull request! 🔧 Your effort and contributions mean a lot to us. 🙌 We'll review it as soon as possible. 🚀"
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
.scikit-mol.code-workspace.swp
scikit-mol.code-workspace
# test data
tests/data/
# setuptools_scm version
scikit_mol/_version.py
notebooks/SLC6A4_active_excape_export.csv
sandbox/
# PyCharm settings
.idea
================================================
FILE: .pre-commit-config.yaml
================================================
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: requirements-txt-fixer
- id: mixed-line-ending
- id: check-yaml
- id: check-json
- id: pretty-format-json
args: ['--autofix']
exclude: .ipynb
- id: check-added-large-files
- id: check-merge-conflict
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.8.6
hooks:
# Run the linter.
- id: ruff
args: [ --fix ]
types_or: [ python, pyi ]
# Run the formatter.
- id: ruff-format
================================================
FILE: .readthedocs.yaml
================================================
# Read the Docs configuration file for MkDocs projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.12"
jobs:
# Use uv to speed up the build
# https://docs.readthedocs.io/en/stable/build-customization.html#install-dependencies-with-uv
pre_create_environment:
- asdf plugin add uv
- asdf install uv 0.5.24
- asdf global uv 0.5.24
create_environment:
- uv venv
install:
- uv sync --group docs
build:
html:
- uv run mkdocs build -d $READTHEDOCS_OUTPUT/html
mkdocs:
configuration: mkdocs.yml
================================================
FILE: .vscode/extensions.json
================================================
{
"recommendations": [
"njpwerner.autodocstring"
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"autoDocstring.docstringFormat": "numpy"
}
================================================
FILE: CITATION.bib
================================================
@article{bjerrum_scikit-mol_2023,
title = {Scikit-{Mol} brings cheminformatics to {Scikit}-{Learn}},
author = {Bjerrum, Esben Jannik and Bachorz, Rafał Adam and Bitton, Adrien and Choung, Oh-hyeon and Chen, Ya and Esposito, Carmen and Ha, Son Viet and Poehlmann, Andreas},
year = {2023},
month = dec,
journal = {ChemRxiv},
url = {https://chemrxiv.org/engage/chemrxiv/article-details/60ef0fc58825826143a82cc0},
doi = {10.26434/chemrxiv-2023-fzqwd},
abstract = {Scikit-Mol is a open-source toolkit that aims to bridge the gap between two well-established toolkits, RDKit and Scikit-Learn, in order to provide a simple interface for building cheminformatics models. By leveraging the strengths of both RDKit and Scikit-Learn, Scikit-Mol provides a powerful platform for creating predictive modeling in drug discovery and materials design. Unlike other toolkits that often integrate both chemistry and machine learning, Scikit-Mol rather aims to be a simple bridge between the two, reducing the maintenance effort required to keep up with changes and new features in e.g. Scikit-Learn. A simple example of Scikit-Mol's functionality is provided, demonstrating its compatibility with Scikit-Learn pipelines. Overall, Scikit-Mol provides a useful and flexible package for building self-contained and self-documented cheminformatics models with minimal maintenance required.},
language = {en},
urldate = {2023-12-06},
keywords = {Cheminformatics, Descriptors, Fingerprints, Machine Learning, RDKit, Scikit-Learn},
note = {preprint}
}
================================================
FILE: CONTRIBUTING.md
================================================
# Contribution
For up-to-date information, see
[docs/contribution.md](docs/contributing.md)
or
[https://scikit-mol.readthedocs.io/en/latest/contributing/](https://scikit-mol.readthedocs.io/en/latest/contributing/)
================================================
FILE: LICENSE
================================================
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
================================================
FILE: MANIFEST.in
================================================
prune .github
exclude .git*
================================================
FILE: Makefile
================================================
sync-notebooks:
uv run jupytext --set-formats docs//notebooks//ipynb,docs//notebooks//scripts//py:percent --sync docs/notebooks/*.ipynb
uv run ruff format "docs/notebooks/"
run-notebooks:
uv run jupytext --execute docs/notebooks/*ipynb
================================================
FILE: README.md
================================================
# scikit-mol

[]()
[](https://pypi.org/project/scikit-mol/)
[](https://anaconda.org/conda-forge/scikit-mol)
[](#)
[](https://www.rdkit.org/)
[](https://github.com/astral-sh/ruff)
## Scikit-Learn classes for molecular vectorization using RDKit
The intended usage is to be able to add molecular vectorization directly into scikit-learn pipelines, so that the final model directly predict on RDKit molecules or SMILES strings
As example with the needed scikit-learn and -mol imports and RDKit mol objects in the mol_list_train and \_test lists:
pipe = Pipeline([('mol_transformer', MorganFingerprintTransformer()), ('Regressor', Ridge())])
pipe.fit(mol_list_train, y_train)
pipe.score(mol_list_test, y_test)
pipe.predict([Chem.MolFromSmiles('c1ccccc1C(=O)C')])
>>> array([4.93858815])
The scikit-learn compatibility should also make it easier to include the fingerprinting step in hyperparameter tuning with scikit-learns utilities
The first draft for the project was created at the [RDKIT UGM 2022 hackathon](https://github.com/rdkit/UGM_2022) 2022-October-14
## Installation
Users can install latest tagged release from pip
```sh
pip install scikit-mol
```
or from conda-forge
```sh
conda install -c conda-forge scikit-mol
```
The conda forge package should get updated shortly after a new tagged release on pypi.
Bleeding edge
```sh
pip install git+https://github.com/EBjerrum/scikit-mol.git
```
## Documentation
Example notebooks and API documentation are now hosted on [https://scikit-mol.readthedocs.io](https://scikit-mol.readthedocs.io/en/latest/)
- [Basic Usage and fingerprint transformers](https://scikit-mol.readthedocs.io/en/latest/notebooks/01_basic_usage/)
- [Descriptor transformer](https://scikit-mol.readthedocs.io/en/latest/notebooks/02_descriptor_transformer/)
- [Pipelining with Scikit-Learn classes](https://scikit-mol.readthedocs.io/en/latest/notebooks/03_example_pipeline/)
- [Molecular standardization](https://scikit-mol.readthedocs.io/en/latest/notebooks/04_standardizer/)
- [Sanitizing SMILES input](https://scikit-mol.readthedocs.io/en/latest/notebooks/05_smiles_sanitization/)
- [Integrated hyperparameter tuning of Scikit-Learn estimator and Scikit-Mol transformer](https://scikit-mol.readthedocs.io/en/latest/notebooks/06_hyperparameter_tuning/)
- [Using parallel execution to speed up descriptor and fingerprint calculations](https://scikit-mol.readthedocs.io/en/latest/notebooks/07_parallel_transforms/)
- [Using skopt for hyperparameter tuning](https://scikit-mol.readthedocs.io/en/latest/notebooks/08_external_library_skopt/)
- [Testing different fingerprints as part of the hyperparameter optimization](https://scikit-mol.readthedocs.io/en/latest/notebooks/09_Combinatorial_Method_Usage_with_FingerPrint_Transformers/)
- [Using pandas output for easy feature importance analysis and combine pre-existing values with new computations](https://scikit-mol.readthedocs.io/en/latest/notebooks/10_pipeline_pandas_output/)
- [Working with pipelines and estimators in safe inference mode for handling prediction on batches with invalid smiles or molecules](https://scikit-mol.readthedocs.io/en/latest/notebooks/11_safe_inference/)
- [Creating custom fingerprint transformers](https://scikit-mol.readthedocs.io/en/latest/notebooks/12_custom_fingerprint_transformer/)
- [Estimating applicability domain using feature based estimators](https://scikit-mol.readthedocs.io/en/latest/notebooks/13_applicability_domain/)
We also put a software note on ChemRxiv. [https://doi.org/10.26434/chemrxiv-2023-fzqwd](https://doi.org/10.26434/chemrxiv-2023-fzqwd)
## Other use-examples
Scikit-Mol has been featured in blog-posts or used in research, some examples which are listed below:
- [Useful ML package for cheminformatics iwatobipen.wordpress.com](https://iwatobipen.wordpress.com/2023/11/12/useful-ml-package-for-cheminformatics-rdkit-cheminformatics-ml/)
- [Boosted trees Data_in_life_blog](https://jhylin.github.io/Data_in_life_blog/posts/19_ML2-3_Boosted_trees/1_adaboost_xgb.html)
- [Konnektor: A Framework for Using Graph Theory to Plan Networks for Free Energy Calculations](https://pubs.acs.org/doi/abs/10.1021/acs.jcim.4c01710)
- [Moldrug algorithm for an automated ligand binding site exploration by 3D aware molecular enumerations](https://doi.org/10.1186/s13321-025-01022-3)
- [RandomNets Improve Neural Network Regression Performance via Implicit Ensembling](https://chemrxiv.org/engage/chemrxiv/article-details/67656cfa81d2151a02603f48)
- [WAE-DTI: Ensemble-based architecture for drug–target interaction prediction using descriptors and embeddings](https://www.sciencedirect.com/science/article/pii/S2352914824001618)
- [Data Driven Estimation of Molecular Log-Likelihood using Fingerprint Key Counting](https://chemrxiv.org/engage/chemrxiv/article-details/661402ee21291e5d1d646651)
- [AUTONOMOUS DRUG DISCOVERY](https://www.proquest.com/openview/3e830e36bc618f263905a99e787c66c6/1?pq-origsite=gscholar&cbl=18750&diss=y)
- [DrugGym: A testbed for the economics of autonomous drug discovery](https://www.biorxiv.org/content/10.1101/2024.05.28.596296v1.abstract)
## Roadmap and Contributing
_Help wanted!_ Are you a PhD student that want a "side-quest" to procrastinate your thesis writing or are you interested in computational chemistry, cheminformatics or simply with an interest in QSAR modelling, Python Programming open-source software? Do you want to learn more about machine learning with Scikit-Learn? Or do you use scikit-mol for your current work and would like to pay a little back to the project and see it improved as well?
With a little bit of help, this project can be improved much faster! Reach to me (Esben), for a discussion about how we can proceed.
Currently, we are working on fixing some deprecation warnings, it's not the most exciting work, but it's important to maintain a little. Later on we need to go over the scikit-learn compatibility and update to some of their newer features on their estimator classes. We're also brewing on some feature enhancements and tests, such as new fingerprints and a more versatile standardizer.
There are more information about how to contribute to the project in [CONTRIBUTING](https://scikit-mol.readthedocs.io/en/latest/contributing/)
## BUGS
Probably still, please check issues at GitHub and report there
## Contributors
Scikit-Mol has been developed as a community effort with contributions from people from many different companies, consortia, foundations and academic institutions.
[Cheminformania Consulting](https://www.cheminformania.com), [Aptuit](https://www.linkedin.com/company/aptuit/), [BASF](https://www.basf.com), [Bayer AG](https://www.bayer.com), [Boehringer Ingelheim](https://www.boehringer-ingelheim.com/), [Chodera Lab (MSKCC)](https://www.choderalab.org/), [EPAM Systems](https://www.epam.com/),[ETH Zürich](https://ethz.ch/en.html), [Evotec](https://www.evotec.com/), [Johannes Gutenberg University](https://www.uni-mainz.de/en/), [Martin Luther University](https://www.uni-halle.de/?lang=en), [Odyssey Therapeutics](https://odysseytx.com/), [Open Molecular Software Foundation](https://omsf.io/), [Openfree.energy](https://openfree.energy/), [Polish Academy of Sciences](https://pasific.pan.pl/polish-academy-of-sciences/), [Productivista](https://www.productivista.com), [Simulations-Plus Inc.](https://www.simulations-plus.com/), [University of Vienna](https://www.univie.ac.at/en/)
- Esben Jannik Bjerrum [@ebjerrum](https://github.com/ebjerrum), esbenbjerrum+scikit_mol@gmail.com
- Carmen Esposito [@cespos](https://github.com/cespos)
- Son Ha [@son-ha-264](https://github.com/son-ha-264)
- Oh-hyeon Choung [@Ohyeon5](https://github.com/Ohyeon5)
- Andreas Poehlmann [@ap--](https://github.com/ap--)
- Ya Chen [@anya-chen](https://github.com/anya-chen)
- Anton Siomchen [@asiomchen](https://github.com/asiomchen)
- Rafał Bachorz [@rafalbachorz](https://github.com/rafalbachorz)
- Adrien Chaton [@adrienchaton](https://github.com/adrienchaton)
- [@VincentAlexanderScholz](https://github.com/VincentAlexanderScholz)
- [@RiesBen](https://github.com/RiesBen)
- [@enricogandini](https://github.com/enricogandini)
- [@mikemhenry](https://github.com/mikemhenry)
- [@c-feldmann](https://github.com/c-feldmann)
- Mieczyslaw Torchala [@mieczyslaw](https://github.com/mieczyslaw)
- Kyle Barbary [@kbarbary](https://github.com/kbarbary)
================================================
FILE: docs/api/fingerprints.base.md
================================================
`scikit_mol.fingerprints.baseclasses`
::: scikit_mol.fingerprints.baseclasses
options:
filters: []
================================================
FILE: docs/api/scikit_mol.applicability.md
================================================
# `scikit-mol.applicability`
::: scikit_mol.applicability
================================================
FILE: docs/api/scikit_mol.conversions.md
================================================
# `scikit-mol.conversions`
::: scikit_mol.conversions
================================================
FILE: docs/api/scikit_mol.core.md
================================================
# `scikit-mol.core`
::: scikit_mol.core
================================================
FILE: docs/api/scikit_mol.descriptors.md
================================================
# `scikit_mol.descriptors`
::: scikit_mol.descriptors
================================================
FILE: docs/api/scikit_mol.fingerprints.md
================================================
::: scikit_mol.fingerprints
options:
filters: ["!Fps"]
inherited_members:
- transform
================================================
FILE: docs/api/scikit_mol.parallel.md
================================================
# `scikit-mol.parallel`
::: scikit_mol.parallel
================================================
FILE: docs/api/scikit_mol.plotting.md
================================================
# `scikit-mol.plotting`
::: scikit_mol.plotting
================================================
FILE: docs/api/scikit_mol.safeinference.md
================================================
# `scikit-mol.safeinference`
::: scikit_mol.safeinference
================================================
FILE: docs/api/scikit_mol.standardizer.md
================================================
# `scikit-mol.standardizer`
::: scikit_mol.standardizer
================================================
FILE: docs/assets/css/tweak-width.css
================================================
/* snippet from datamol.io */
@media only screen and (min-width: 76.25em) {
.md-main__inner {
max-width: none;
padding-left: 2em;
padding-left: 2em;
}
.md-sidebar--primary {
left: 0;
}
.md-sidebar--secondary {
right: 0;
margin-left: 0;
-webkit-transform: none;
transform: none;
}
}
================================================
FILE: docs/assets/js/readthedocs.js
================================================
// Add server-side search
document.addEventListener("DOMContentLoaded", function(event) {
// Trigger Read the Docs' search addon instead of Material MkDocs default
document.querySelector(".md-search__input").addEventListener("focus", (e) => {
const event = new CustomEvent("readthedocs-search-show");
document.dispatchEvent(event);
});
});
// Use CustomEvent to generate the version selector
document.addEventListener(
"readthedocs-addons-data-ready",
function (event) {
const config = event.detail.data();
const versioning = `
`;
document.querySelector(".md-header__topic").insertAdjacentHTML("beforeend", versioning);
});
================================================
FILE: docs/contributing.md
================================================
# Contribution
Thanks for your interest in contributing to the project. Please read on in the sections that apply.
## Discord Server
We have a discord server for chats and discussion, ask for an invitation: esbenbjerrum+scikit_mol@gmail.com
## Installation
We use [uv] for managing the virtual environment. You can install it with:
```sh
curl -LsSf https://astral.sh/uv/install.sh | sh
```
For more information and other installation methods see [documentation](https://docs.astral.sh/uv/)
Clone and install in editable more like this
```sh
git clone git@github.com:EBjerrum/scikit-mol.git
uv sync --dev
```
After that you could either activate venv and run commands as usual:
```sh
source .venv/bin/activate
pytest -v --cov=scikit_mol
```
or use `uv run` to run commands in the venv (automatically check that environment is up to date):
```sh
uv run pytest -v --cov=scikit_mol
```
`uv.lock` contains the pinned dependencies and is used to recreate the environment. Make sure to update it when adding new dependencies. (handled automatically when using `uv run` or manually with `uv lock`)
## Code Quality
We use [ruff](https://github.com/astral-sh/ruff) to lint and format the code. The configuration is in the [ruff.toml](https://github.com/EBjerrum/scikit-mol/blob/main/ruff.toml) file. The CI will fail if the code is not formatted correctly. You can run the linter and formatter locally with:
```sh
ruff format scikit_mol
ruff check --fix scikit_mol
```
We also have pre-commit hooks that will run the linter and formatter before you commit, and we highly recommend you to use them. You can install them with:
```sh
pre-commit install
```
For more information on pre-commit see [documentation](https://pre-commit.com/).
## Adding transformers
The projects transformers subclasses the BaseEstimator and Transformer mixin classes from sklearn. Their documentation page contains information on what requisites are necessary [https://scikit-learn.org/stable/developers/develop.html](https://scikit-learn.org/stable/developers/develop.html). Most notably:
- The arguments accepted by **init** should all be keyword arguments with a default value.
- Every keyword argument accepted by **init** should correspond to an attribute on the instance.
- - There should be no logic, not even input validation, and the parameters should not be changed inside the **init** function.
Scikit-learn classes depends on this in order to for e.g. the `.get_params()`, `.set_params()`, cloning abilities and representation rendering to work.
- With the new error handling, falsy objects need to return masked arrays or arrays with `np.nan` (for float dtype)
### Tips
- We have observed that some external tools used "exotic" types such at `np.int64` when doing hyperparameter tuning. It is thus necessary do defensive programming to cast parameters to standard types before making calls to rdkit functions. This behaviour is tested in the `test_parameter_types` test
- `@property` getters and setters can be used if additional logic are needed when setting the attributes from the keywords while at the same time adhering to the sklearn requisites.
- Some RDKit features uses objects as generators which may not be picklable. If instantiated and added to the object as an attribute rather than instantiated at each function call for individual molecules, these should thus be removed and recreated via overloading the `_get_state()` and `_set_state()` methods.
See [MHFingerprintTransformer](https://github.com/EBjerrum/scikit-mol/blob/main/scikit_mol/fingerprints/minhash.py#L11) for an example.
## Module organisation
Currently, we have multiple classes in the same file, if they are the same type. This may change in the future.
## Docstrings
We should ultimately consolidate on the NumPy docstring format [https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard](https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard) which is also used by SciPy and other scikits.
## Typehints
parameters and output of methods should preferably be using typehints
## Testing
New transformer classes should be added to the pytest tests in the tests directory. A lot of tests are made general, and tests aspects of the transformers that are needed for sklearn compliance or other features. The transformer is then added to a fixture and can be added to the lists of transformer objects that are run by these test. Specific tests may also be necessary to set up. As example the assert_transformer_set_params needs a list of non-default parameters in order to set the set_params functionality of the object.
Scikit-Learn has a check_estimator that we should strive to get to work, some classes of scikit-mol currently does not pass all tests.
## Notebooks
Another way of contributing is by providing notebooks with examples on how to use the project to build models together with Scikit-Learn and other tools. There are .ipynb files in the `docs/notebooks` and .py files in the `script` subfolder as the first are useful for online rendering in the documentation, whereas the latter is useful for sub version control.
If you want to create new notebook you can first create .ipynb file, and then you run `make sync-notebooks` to create the corresponding .py file for the commit.
If you updated any of the existing py/ipynb files, you can run `make sync-notebooks` to update the outdated file in the pair. The .py files are used for nice diffs, and the .ipynb files are used for rendering in the documentation.
`make sync-notebooks` will sync all the notebooks with the .py files in the `scripts` folder.
`make run-notebooks` will sync, run and save the notebooks, expects an ipython kernel with scikit-mol installed.
If you only want to sync and run a single notebook if you are working on updating one you can adapt the commands from the MakeFile
```bash
uv run jupytext --set-formats docs//notebooks//ipynb,docs//notebooks//scripts//py:percent --sync docs/notebooks/XX_YourNotebook.ipynb
uv run ruff format "docs/notebooks/XX_YourNotebook.ipynb"
uv run jupytext --execute docs/notebooks/XX_YourNotebook.ipynb
```
## Documentation
We use [MkDocs](https://www.mkdocs.org/) to host scikit-mol documentation on ReadTheDocs. If you're making some changes to the documentation or just what to see live preview of your docstring you can take a look at rendered documentation.
Install documentation dependencies:
```sh
uv sync --group docs
```
Start server:
```sh
uv run mkdocs serve
```
Go to http://127.0.0.1:8000 to see the documentation
## Release
### PyPi
To release a new version on PyPi, you need to create and push new tag in v0.0.0 format then workflow will automatically build and upload the package to PyPi. Additionally, the release draft with autogenerated notes and signed distribution files will be added to the GitHub release page. What is left is to publish the release, after checking that the notes are correct.
### Conda
When you make a release on PyPi the conda-forge bot will automatically make a PR that updates the Conda feedstock to the new version. If new main package dependencies or pins are changed on dependencies, those changes will need to be added to the PR in the feedstocks [https://github.com/conda-forge/scikit-mol-feedstock/blob/main/recipe/meta.yaml](https://github.com/conda-forge/scikit-mol-feedstock/blob/main/recipe/meta.yaml). I.e. the run section needs to correspond to the `dependencies = [` section in pyproject.toml. If there is just a pure code change then all we have do to is merge in the PR and that will update the package on conda-forge. See https://conda-forge.org/docs/maintainer/updating_pkgs/ for more information
================================================
FILE: docs/index.md
================================================
# scikit-mol

[]()
[](https://pypi.org/project/scikit-mol/)
[](https://anaconda.org/conda-forge/scikit-mol)
[](#)
[](https://www.rdkit.org/)
[](https://github.com/astral-sh/ruff)
## Scikit-Learn classes for molecular vectorization using RDKit
The intended usage is to be able to add molecular vectorization directly into scikit-learn pipelines, so that the final model directly predict on RDKit molecules or SMILES strings
As example with the needed scikit-learn and -mol imports and RDKit mol objects in the mol_list_train and \_test lists:
pipe = Pipeline([('mol_transformer', MorganFingerprintTransformer()), ('Regressor', Ridge())])
pipe.fit(mol_list_train, y_train)
pipe.score(mol_list_test, y_test)
pipe.predict([Chem.MolFromSmiles('c1ccccc1C(=O)C')])
>>> array([4.93858815])
The scikit-learn compatibility should also make it easier to include the fingerprinting step in hyperparameter tuning with scikit-learns utilities
The first draft for the project was created at the [RDKIT UGM 2022 hackathon](https://github.com/rdkit/UGM_2022) 2022-October-14
## Installation
Users can install latest tagged release from pip
```sh
pip install scikit-mol
```
or from conda-forge
```sh
conda install -c conda-forge scikit-mol
```
The conda forge package should get updated shortly after a new tagged release on pypi.
Bleeding edge
```sh
pip install git+https://github.com/EBjerrum/scikit-mol.git
```
## Documentation
Example notebooks and API documentation are now hosted on [https://scikit-mol.readthedocs.io](https://scikit-mol.readthedocs.io/en/latest/)
- [Basic Usage and fingerprint transformers](https://scikit-mol.readthedocs.io/en/latest/notebooks/01_basic_usage/)
- [Descriptor transformer](https://scikit-mol.readthedocs.io/en/latest/notebooks/02_descriptor_transformer/)
- [Pipelining with Scikit-Learn classes](https://scikit-mol.readthedocs.io/en/latest/notebooks/03_example_pipeline/)
- [Molecular standardization](https://scikit-mol.readthedocs.io/en/latest/notebooks/04_standardizer/)
- [Sanitizing SMILES input](https://scikit-mol.readthedocs.io/en/latest/notebooks/05_smiles_sanitization/)
- [Integrated hyperparameter tuning of Scikit-Learn estimator and Scikit-Mol transformer](https://scikit-mol.readthedocs.io/en/latest/notebooks/06_hyperparameter_tuning/)
- [Using parallel execution to speed up descriptor and fingerprint calculations](https://scikit-mol.readthedocs.io/en/latest/notebooks/07_parallel_transforms/)
- [Using skopt for hyperparameter tuning](https://scikit-mol.readthedocs.io/en/latest/notebooks/08_external_library_skopt/)
- [Testing different fingerprints as part of the hyperparameter optimization](https://scikit-mol.readthedocs.io/en/latest/notebooks/09_Combinatorial_Method_Usage_with_FingerPrint_Transformers/)
- [Using pandas output for easy feature importance analysis and combine pre-existing values with new computations](https://scikit-mol.readthedocs.io/en/latest/notebooks/10_pipeline_pandas_output/)
- [Working with pipelines and estimators in safe inference mode for handling prediction on batches with invalid smiles or molecules](https://scikit-mol.readthedocs.io/en/latest/notebooks/11_safe_inference/)
- [Creating custom fingerprint transformers](https://scikit-mol.readthedocs.io/en/latest/notebooks/12_custom_fingerprint_transformer/)
- [Estimating applicability domain using feature based estimators](https://scikit-mol.readthedocs.io/en/latest/notebooks/13_applicability_domain/)
We also put a software note on ChemRxiv. [https://doi.org/10.26434/chemrxiv-2023-fzqwd](https://doi.org/10.26434/chemrxiv-2023-fzqwd)
## Other use-examples
Scikit-Mol has been featured in blog-posts or used in research, some examples which are listed below:
- [Useful ML package for cheminformatics iwatobipen.wordpress.com](https://iwatobipen.wordpress.com/2023/11/12/useful-ml-package-for-cheminformatics-rdkit-cheminformatics-ml/)
- [Boosted trees Data_in_life_blog](https://jhylin.github.io/Data_in_life_blog/posts/19_ML2-3_Boosted_trees/1_adaboost_xgb.html)
- [Konnektor: A Framework for Using Graph Theory to Plan Networks for Free Energy Calculations](https://pubs.acs.org/doi/abs/10.1021/acs.jcim.4c01710)
- [Moldrug algorithm for an automated ligand binding site exploration by 3D aware molecular enumerations](https://doi.org/10.1186/s13321-025-01022-3)
- [RandomNets Improve Neural Network Regression Performance via Implicit Ensembling](https://chemrxiv.org/engage/chemrxiv/article-details/67656cfa81d2151a02603f48)
- [WAE-DTI: Ensemble-based architecture for drug–target interaction prediction using descriptors and embeddings](https://www.sciencedirect.com/science/article/pii/S2352914824001618)
- [Data Driven Estimation of Molecular Log-Likelihood using Fingerprint Key Counting](https://chemrxiv.org/engage/chemrxiv/article-details/661402ee21291e5d1d646651)
- [AUTONOMOUS DRUG DISCOVERY](https://www.proquest.com/openview/3e830e36bc618f263905a99e787c66c6/1?pq-origsite=gscholar&cbl=18750&diss=y)
- [DrugGym: A testbed for the economics of autonomous drug discovery](https://www.biorxiv.org/content/10.1101/2024.05.28.596296v1.abstract)
## Roadmap and Contributing
_Help wanted!_ Are you a PhD student that want a "side-quest" to procrastinate your thesis writing or are you interested in computational chemistry, cheminformatics or simply with an interest in QSAR modelling, Python Programming open-source software? Do you want to learn more about machine learning with Scikit-Learn? Or do you use scikit-mol for your current work and would like to pay a little back to the project and see it improved as well?
With a little bit of help, this project can be improved much faster! Reach to me (Esben), for a discussion about how we can proceed.
Currently, we are working on fixing some deprecation warnings, it's not the most exciting work, but it's important to maintain a little. Later on we need to go over the scikit-learn compatibility and update to some of their newer features on their estimator classes. We're also brewing on some feature enhancements and tests, such as new fingerprints and a more versatile standardizer.
There are more information about how to contribute to the project in [CONTRIBUTING](https://scikit-mol.readthedocs.io/en/latest/contributing/)
## BUGS
Probably still, please check issues at GitHub and report there
## Contributors
Scikit-Mol has been developed as a community effort with contributions from people from many different companies, consortia, foundations and academic institutions.
[Cheminformania Consulting](https://www.cheminformania.com), [Aptuit](https://www.linkedin.com/company/aptuit/), [BASF](https://www.basf.com), [Bayer AG](https://www.bayer.com), [Boehringer Ingelheim](https://www.boehringer-ingelheim.com/), [Chodera Lab (MSKCC)](https://www.choderalab.org/), [EPAM Systems](https://www.epam.com/),[ETH Zürich](https://ethz.ch/en.html), [Evotec](https://www.evotec.com/), [Johannes Gutenberg University](https://www.uni-mainz.de/en/), [Martin Luther University](https://www.uni-halle.de/?lang=en), [Odyssey Therapeutics](https://odysseytx.com/), [Open Molecular Software Foundation](https://omsf.io/), [Openfree.energy](https://openfree.energy/), [Polish Academy of Sciences](https://pasific.pan.pl/polish-academy-of-sciences/), [Productivista](https://www.productivista.com), [Simulations-Plus Inc.](https://www.simulations-plus.com/), [University of Vienna](https://www.univie.ac.at/en/)
- Esben Jannik Bjerrum [@ebjerrum](https://github.com/ebjerrum), esbenbjerrum+scikit_mol@gmail.com
- Carmen Esposito [@cespos](https://github.com/cespos)
- Son Ha [@son-ha-264](https://github.com/son-ha-264)
- Oh-hyeon Choung [@Ohyeon5](https://github.com/Ohyeon5)
- Andreas Poehlmann [@ap--](https://github.com/ap--)
- Ya Chen [@anya-chen](https://github.com/anya-chen)
- Anton Siomchen [@asiomchen](https://github.com/asiomchen)
- Rafał Bachorz [@rafalbachorz](https://github.com/rafalbachorz)
- Adrien Chaton [@adrienchaton](https://github.com/adrienchaton)
- [@VincentAlexanderScholz](https://github.com/VincentAlexanderScholz)
- [@RiesBen](https://github.com/RiesBen)
- [@enricogandini](https://github.com/enricogandini)
- [@mikemhenry](https://github.com/mikemhenry)
- [@c-feldmann](https://github.com/c-feldmann)
- Mieczyslaw Torchala [@mieczyslaw](https://github.com/mieczyslaw)
- Kyle Barbary [@kbarbary](https://github.com/kbarbary)
================================================
FILE: docs/notebooks/01_basic_usage.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"id": "aa079ac3",
"metadata": {},
"source": [
"# Scikit-Mol\n",
"## scikit-learn compatible RDKit transformers\n",
"\n",
"Scikit-mol is a collection of scikit-learn compatible transformer classes that integrate into the scikit-learn framework and thus bridge between the molecular information in form of RDKit molecules or SMILES and the machine learning framework from scikit-learn\n"
]
},
{
"cell_type": "markdown",
"id": "76d24789",
"metadata": {},
"source": [
"The transformer classes are easy to load, configure and use to process molecular information into vectorized formats using fingerprinters or collections of descriptors. For demonstration purposes, let's load a MorganTransformer, that can convert a list of RDKit molecular objects into a numpy array of morgan fingerprints. First create some molecules from SMILES strings."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "2c8cad03",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:29.627872Z",
"iopub.status.busy": "2025-05-08T16:22:29.627571Z",
"iopub.status.idle": "2025-05-08T16:22:29.632065Z",
"shell.execute_reply": "2025-05-08T16:22:29.631373Z"
}
},
"outputs": [],
"source": [
"from IPython.core.display import HTML"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "8d5b2333",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:29.634712Z",
"iopub.status.busy": "2025-05-08T16:22:29.634423Z",
"iopub.status.idle": "2025-05-08T16:22:29.845389Z",
"shell.execute_reply": "2025-05-08T16:22:29.844169Z"
}
},
"outputs": [],
"source": [
"from rdkit import Chem\n",
"\n",
"smiles_strings = [\n",
" \"C12C([C@@H](OC(C=3C=CC(=CC3)F)C=4C=CC(=CC4)F)CC(N1CCCCCC5=CC=CC=C5)CC2)C(=O)OC\",\n",
" \"O(C1=NC=C2C(CN(CC2=C1)C)C3=CC=C(OC)C=C3)CCCN(CC)CC\",\n",
" \"O=S(=O)(N(CC=1C=CC2=CC=CC=C2C1)[C@@H]3CCNC3)C\",\n",
" \"C1(=C2C(CCCC2O)=NC=3C1=CC=CC3)NCC=4C=CC(=CC4)Cl\",\n",
" \"C1NC[C@@H](C1)[C@H](OC=2C=CC(=NC2C)OC)CC(C)C\",\n",
" \"FC(F)(F)C=1C(CN(C2CCNCC2)CC(CC)CC)=CC=CC1\",\n",
"]\n",
"\n",
"mols = [Chem.MolFromSmiles(smiles) for smiles in smiles_strings]"
]
},
{
"cell_type": "markdown",
"id": "b9a588c7",
"metadata": {},
"source": [
"Next we import the Morgan fingerprint transformer"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "0a625dda",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:29.850211Z",
"iopub.status.busy": "2025-05-08T16:22:29.848822Z",
"iopub.status.idle": "2025-05-08T16:22:30.986417Z",
"shell.execute_reply": "2025-05-08T16:22:30.984810Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"MorganFingerprintTransformer(radius=3)\n"
]
}
],
"source": [
"from scikit_mol.fingerprints import MorganFingerprintTransformer\n",
"\n",
"transformer = MorganFingerprintTransformer(radius=3)\n",
"print(transformer)"
]
},
{
"cell_type": "markdown",
"id": "355610d1",
"metadata": {},
"source": [
"It actually renders as a cute little interactive block in the Jupyter notebook and lists the options that are not the default values. If we print it, it also gives the information on the settings.\n",
"\n",
"\n",
"\n",
"The graphical representation is probably nice when working with complex pipelines. However, the graphical representation doesn't work when previewing the notebook on GitHub and sometimes nbviewer.org, so for the rest of these scikit-mol notebook examples, we'll use the print() output."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "9a801d0f",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:30.991850Z",
"iopub.status.busy": "2025-05-08T16:22:30.990911Z",
"iopub.status.idle": "2025-05-08T16:22:31.011512Z",
"shell.execute_reply": "2025-05-08T16:22:31.010309Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"
MorganFingerprintTransformer(radius=3)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
MorganFingerprintTransformer(radius=3)
"
],
"text/plain": [
"MorganFingerprintTransformer(radius=3)"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"transformer"
]
},
{
"cell_type": "markdown",
"id": "556858b4",
"metadata": {},
"source": [
"If we want to get all the settings explicitly, we can use the .get_params() method."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "500dc6f7",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:31.015226Z",
"iopub.status.busy": "2025-05-08T16:22:31.014511Z",
"iopub.status.idle": "2025-05-08T16:22:31.022448Z",
"shell.execute_reply": "2025-05-08T16:22:31.021051Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"{'fpSize': 2048,\n",
" 'n_jobs': None,\n",
" 'radius': 3,\n",
" 'safe_inference_mode': False,\n",
" 'useBondTypes': True,\n",
" 'useChirality': False,\n",
" 'useCounts': False,\n",
" 'useFeatures': False}"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"parameters = transformer.get_params()\n",
"parameters"
]
},
{
"cell_type": "markdown",
"id": "d453fa33",
"metadata": {},
"source": [
"The corresponding .set_params() method can be used to update the settings from options or from a dictionary (via ** unpackaging). The get_params and set_params methods are sometimes used by sklearn, as example hyperparameter search objects."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "3a27b07a",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:31.026293Z",
"iopub.status.busy": "2025-05-08T16:22:31.025546Z",
"iopub.status.idle": "2025-05-08T16:22:31.032975Z",
"shell.execute_reply": "2025-05-08T16:22:31.031700Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"MorganFingerprintTransformer(fpSize=256)\n"
]
}
],
"source": [
"parameters[\"radius\"] = 2\n",
"parameters[\"fpSize\"] = 256\n",
"transformer.set_params(**parameters)\n",
"print(transformer)"
]
},
{
"cell_type": "markdown",
"id": "3dd372d3",
"metadata": {},
"source": [
"Transformation is easy, simply use the .transform() method. For sklearn compatibility the scikit-learn transformers also have a .fit_transform() method, but it is usually not fitting anything."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "0f141920",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:31.036752Z",
"iopub.status.busy": "2025-05-08T16:22:31.036118Z",
"iopub.status.idle": "2025-05-08T16:22:31.043904Z",
"shell.execute_reply": "2025-05-08T16:22:31.042561Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"fps is a with shape (6, 256) and data type uint8\n"
]
}
],
"source": [
"fps = transformer.transform(mols)\n",
"print(f\"fps is a {type(fps)} with shape {fps.shape} and data type {fps.dtype}\")"
]
},
{
"cell_type": "markdown",
"id": "9cb75226",
"metadata": {},
"source": [
"For sklearn compatibility, the transform function can be given a second parameter, usually representing the targets in the machine learning, but it is simply ignored most of the time"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "481e527f",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:31.047228Z",
"iopub.status.busy": "2025-05-08T16:22:31.046700Z",
"iopub.status.idle": "2025-05-08T16:22:31.054569Z",
"shell.execute_reply": "2025-05-08T16:22:31.053275Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"array([[0, 1, 0, ..., 0, 0, 0],\n",
" [1, 0, 0, ..., 0, 0, 1],\n",
" [1, 0, 0, ..., 0, 0, 0],\n",
" [0, 0, 0, ..., 0, 0, 1],\n",
" [1, 1, 0, ..., 0, 0, 0],\n",
" [1, 1, 0, ..., 0, 0, 0]], shape=(6, 256), dtype=uint8)"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y = range(len(mols))\n",
"transformer.transform(mols, y)"
]
},
{
"cell_type": "markdown",
"id": "500cec09",
"metadata": {},
"source": [
"Sometimes we may want to transform SMILES into molecules, and scikit-mol also has a transformer for that. It simply takes a list of SMILES and produces a list of RDKit molecules, this may come in handy when building pipelines for machine learning models, as we will demo in another notebook."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "7773a5a0",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:31.057901Z",
"iopub.status.busy": "2025-05-08T16:22:31.057134Z",
"iopub.status.idle": "2025-05-08T16:22:31.064119Z",
"shell.execute_reply": "2025-05-08T16:22:31.063046Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"SmilesToMolTransformer()\n"
]
}
],
"source": [
"from scikit_mol.conversions import SmilesToMolTransformer\n",
"\n",
"smi2mol = SmilesToMolTransformer()\n",
"print(smi2mol)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "fa484453",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:31.067178Z",
"iopub.status.busy": "2025-05-08T16:22:31.066755Z",
"iopub.status.idle": "2025-05-08T16:22:31.074756Z",
"shell.execute_reply": "2025-05-08T16:22:31.073587Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[]\n",
" []\n",
" []\n",
" []\n",
" []\n",
" []]\n"
]
}
],
"source": [
"print(smi2mol.transform(smiles_strings))"
]
}
],
"metadata": {
"jupytext": {
"formats": "docs//notebooks//ipynb,docs//notebooks//scripts//py:percent"
},
"kernelspec": {
"display_name": "Python 3.9.4 ('rdkit')",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
================================================
FILE: docs/notebooks/02_descriptor_transformer.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"id": "e3cf34ca",
"metadata": {},
"source": [
"# Desc2DTransformer: RDKit descriptors transformer\n",
"\n",
"The descriptors transformer can convert molecules into a list of RDKit descriptors. It largely follows the API of the other transformers, but has a few extra methods and properties to manage the descriptors."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "81745b1f",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:32.631647Z",
"iopub.status.busy": "2025-05-08T16:22:32.631311Z",
"iopub.status.idle": "2025-05-08T16:22:34.194489Z",
"shell.execute_reply": "2025-05-08T16:22:34.193202Z"
},
"lines_to_next_cell": 0
},
"outputs": [],
"source": [
"from rdkit import Chem\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from scikit_mol.descriptors import MolecularDescriptorTransformer"
]
},
{
"cell_type": "markdown",
"id": "2293e9e6",
"metadata": {},
"source": [
"After instantiation of the descriptor transformer, we can query which descriptors it found available in the RDKit framework."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "dd9a2ad0",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:34.198567Z",
"iopub.status.busy": "2025-05-08T16:22:34.197421Z",
"iopub.status.idle": "2025-05-08T16:22:34.206453Z",
"shell.execute_reply": "2025-05-08T16:22:34.205342Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"There are 217 available descriptors\n",
"The first five descriptor names: ['MaxAbsEStateIndex', 'MaxEStateIndex', 'MinAbsEStateIndex', 'MinEStateIndex', 'qed']\n"
]
}
],
"source": [
"descriptor = MolecularDescriptorTransformer()\n",
"available_descriptors = descriptor.available_descriptors\n",
"print(f\"There are {len(available_descriptors)} available descriptors\")\n",
"print(f\"The first five descriptor names: {available_descriptors[:5]}\")"
]
},
{
"cell_type": "markdown",
"id": "110c00c0",
"metadata": {},
"source": [
"We can transform molecules to their descriptor profiles"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "4431a910",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:34.210875Z",
"iopub.status.busy": "2025-05-08T16:22:34.210262Z",
"iopub.status.idle": "2025-05-08T16:22:34.353857Z",
"shell.execute_reply": "2025-05-08T16:22:34.352652Z"
}
},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"smiles_list = [\"CCCC\", \"c1ccccc1\"]\n",
"mols = [Chem.MolFromSmiles(smiles) for smiles in smiles_list]\n",
"\n",
"features = descriptor.transform(mols)\n",
"_ = plt.plot(np.array(features).T)"
]
},
{
"cell_type": "markdown",
"id": "fdcb0698",
"metadata": {},
"source": [
"If we only want some of them, this can be specified at object instantiation."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "6caa9a54",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:34.357638Z",
"iopub.status.busy": "2025-05-08T16:22:34.356566Z",
"iopub.status.idle": "2025-05-08T16:22:34.363282Z",
"shell.execute_reply": "2025-05-08T16:22:34.362201Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Selected descriptors are ['HeavyAtomCount', 'FractionCSP3', 'RingCount', 'MolLogP', 'MolWt']\n"
]
}
],
"source": [
"some_descriptors = MolecularDescriptorTransformer(\n",
" desc_list=[\"HeavyAtomCount\", \"FractionCSP3\", \"RingCount\", \"MolLogP\", \"MolWt\"]\n",
")\n",
"print(f\"Selected descriptors are {some_descriptors.selected_descriptors}\")\n",
"features = some_descriptors.transform(mols)"
]
},
{
"cell_type": "markdown",
"id": "52eaef77",
"metadata": {},
"source": [
"If we want to update the selected descriptors on an already existing object, this can be done via the .set_params() method"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "78fc5691",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:34.366550Z",
"iopub.status.busy": "2025-05-08T16:22:34.366050Z",
"iopub.status.idle": "2025-05-08T16:22:34.372939Z",
"shell.execute_reply": "2025-05-08T16:22:34.371839Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"MolecularDescriptorTransformer(desc_list=['HeavyAtomCount', 'FractionCSP3',\n",
" 'RingCount'])\n"
]
}
],
"source": [
"print(\n",
" some_descriptors.set_params(\n",
" desc_list=[\"HeavyAtomCount\", \"FractionCSP3\", \"RingCount\"]\n",
" )\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "310a2a0d",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"jupytext": {
"formats": "docs//notebooks//ipynb,docs//notebooks//scripts//py:percent"
},
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
================================================
FILE: docs/notebooks/03_example_pipeline.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"id": "e7c43298",
"metadata": {},
"source": [
"# Pipelining the scikit-mol transformer\n",
"\n",
"One of the very usable things with scikit-learn are their pipelines. With pipelines different scikit-learn transformers can be stacked and operated on just as a single model object. In this example we will build a simple model that can predict directly on RDKit molecules and then expand it to one that predicts directly on SMILES strings\n",
"\n",
"First some needed imports and a dataset"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "79139b10",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:35.876773Z",
"iopub.status.busy": "2025-05-08T16:22:35.876261Z",
"iopub.status.idle": "2025-05-08T16:22:36.754601Z",
"shell.execute_reply": "2025-05-08T16:22:36.753459Z"
}
},
"outputs": [],
"source": [
"import os\n",
"import rdkit\n",
"from rdkit import Chem\n",
"from rdkit.Chem import PandasTools\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"from time import time\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "17a9cdd7",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:36.758840Z",
"iopub.status.busy": "2025-05-08T16:22:36.758015Z",
"iopub.status.idle": "2025-05-08T16:22:36.767668Z",
"shell.execute_reply": "2025-05-08T16:22:36.766504Z"
},
"lines_to_next_cell": 0
},
"outputs": [],
"source": [
"csv_file = \"../../tests/data/SLC6A4_active_excapedb_subset.csv\" # Hmm, maybe better to download directly\n",
"data = pd.read_csv(csv_file)"
]
},
{
"cell_type": "markdown",
"id": "066131b8",
"metadata": {},
"source": [
"The dataset is a subset of the SLC6A4 actives from ExcapeDB. They are hand selected to give test set performance despite the small size, and are provided as example data only and should not be used to build serious QSAR models.\n",
"\n",
"We add RDKit mol objects to the dataframe with pandastools and check that all conversions went well."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "a3ec0a23",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:36.770992Z",
"iopub.status.busy": "2025-05-08T16:22:36.770360Z",
"iopub.status.idle": "2025-05-08T16:22:36.828093Z",
"shell.execute_reply": "2025-05-08T16:22:36.826677Z"
},
"lines_to_next_cell": 0
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 out of 200 SMILES failed in conversion\n"
]
}
],
"source": [
"PandasTools.AddMoleculeColumnToFrame(data, smilesCol=\"SMILES\")\n",
"print(f\"{data.ROMol.isna().sum()} out of {len(data)} SMILES failed in conversion\")"
]
},
{
"cell_type": "markdown",
"id": "eccaf4af",
"metadata": {},
"source": [
"Then, let's import some tools from scikit-learn and two transformers from scikit-mol"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "4eb8f0fa",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:36.830959Z",
"iopub.status.busy": "2025-05-08T16:22:36.830663Z",
"iopub.status.idle": "2025-05-08T16:22:37.516946Z",
"shell.execute_reply": "2025-05-08T16:22:37.515550Z"
}
},
"outputs": [],
"source": [
"from sklearn.pipeline import Pipeline\n",
"from sklearn.linear_model import Ridge\n",
"from sklearn.model_selection import train_test_split\n",
"from scikit_mol.fingerprints import MorganFingerprintTransformer\n",
"from scikit_mol.conversions import SmilesToMolTransformer"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "99edec0f",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:37.521222Z",
"iopub.status.busy": "2025-05-08T16:22:37.520115Z",
"iopub.status.idle": "2025-05-08T16:22:37.527537Z",
"shell.execute_reply": "2025-05-08T16:22:37.526440Z"
}
},
"outputs": [],
"source": [
"mol_list_train, mol_list_test, y_train, y_test = train_test_split(\n",
" data.ROMol, data.pXC50, random_state=0\n",
")"
]
},
{
"cell_type": "markdown",
"id": "b8380817",
"metadata": {},
"source": [
"After a split into train and test, we'll build the first pipeline"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "a27d6ff9",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:37.531062Z",
"iopub.status.busy": "2025-05-08T16:22:37.530349Z",
"iopub.status.idle": "2025-05-08T16:22:37.539115Z",
"shell.execute_reply": "2025-05-08T16:22:37.538026Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Pipeline(steps=[('mol_transformer', MorganFingerprintTransformer()),\n",
" ('Regressor', Ridge())])\n"
]
}
],
"source": [
"pipe = Pipeline(\n",
" [(\"mol_transformer\", MorganFingerprintTransformer()), (\"Regressor\", Ridge())]\n",
")\n",
"print(pipe)"
]
},
{
"cell_type": "markdown",
"id": "6c12f9a8",
"metadata": {},
"source": [
"We can do the fit by simply providing the list of RDKit molecule objects"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "634ca919",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:37.542129Z",
"iopub.status.busy": "2025-05-08T16:22:37.541844Z",
"iopub.status.idle": "2025-05-08T16:22:37.609556Z",
"shell.execute_reply": "2025-05-08T16:22:37.608271Z"
},
"lines_to_next_cell": 0
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Train score is :1.00\n",
"Test score is :0.55\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
}
],
"source": [
"pipe.fit(mol_list_train, y_train)\n",
"print(f\"Train score is :{pipe.score(mol_list_train,y_train):0.2F}\")\n",
"print(f\"Test score is :{pipe.score(mol_list_test, y_test):0.2F}\")"
]
},
{
"cell_type": "markdown",
"id": "8440cc5a",
"metadata": {},
"source": [
"Nevermind the performance, or the exact value of the prediction, this is for demonstration purpures. We can easily predict on lists of molecules"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "f4431aab",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:37.613501Z",
"iopub.status.busy": "2025-05-08T16:22:37.613074Z",
"iopub.status.idle": "2025-05-08T16:22:37.625937Z",
"shell.execute_reply": "2025-05-08T16:22:37.624623Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"array([6.00400299])"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pipe.predict([Chem.MolFromSmiles(\"c1ccccc1C(=O)[OH]\")])"
]
},
{
"cell_type": "markdown",
"id": "a60e242b",
"metadata": {},
"source": [
"We can also expand the already fitted pipeline, how about creating a pipeline that can predict directly from SMILES? With scikit-mol that is easy!"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "a908097d",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:37.630016Z",
"iopub.status.busy": "2025-05-08T16:22:37.629320Z",
"iopub.status.idle": "2025-05-08T16:22:37.640274Z",
"shell.execute_reply": "2025-05-08T16:22:37.639075Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Pipeline(steps=[('smiles_transformer', SmilesToMolTransformer()),\n",
" ('pipe',\n",
" Pipeline(steps=[('mol_transformer',\n",
" MorganFingerprintTransformer()),\n",
" ('Regressor', Ridge())]))])\n"
]
}
],
"source": [
"smiles_pipe = Pipeline(\n",
" [(\"smiles_transformer\", SmilesToMolTransformer()), (\"pipe\", pipe)]\n",
")\n",
"print(smiles_pipe)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "0124653c",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:37.643282Z",
"iopub.status.busy": "2025-05-08T16:22:37.642781Z",
"iopub.status.idle": "2025-05-08T16:22:37.655561Z",
"shell.execute_reply": "2025-05-08T16:22:37.652513Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"array([6.00400299])"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"smiles_pipe.predict([\"c1ccccc1C(=O)[OH]\"])"
]
},
{
"cell_type": "markdown",
"id": "069e2d01",
"metadata": {},
"source": [
"From here, the pipelines could be pickled, and later loaded for easy prediction on RDKit molecule objects or SMILES in other scripts. The transformation with the MorganTransformer will be the same as during fitting, so no need to remember if radius 2 or 3 was used for this or that model, as it is already in the pipeline itself. If we need to see the parameters for a particular pipeline of model, we can always get the non default settings via print or all settings with .get_params()."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "63c8ef60",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:37.659747Z",
"iopub.status.busy": "2025-05-08T16:22:37.658755Z",
"iopub.status.idle": "2025-05-08T16:22:37.669836Z",
"shell.execute_reply": "2025-05-08T16:22:37.668406Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"{'memory': None,\n",
" 'steps': [('smiles_transformer', SmilesToMolTransformer()),\n",
" ('pipe',\n",
" Pipeline(steps=[('mol_transformer', MorganFingerprintTransformer()),\n",
" ('Regressor', Ridge())]))],\n",
" 'transform_input': None,\n",
" 'verbose': False,\n",
" 'smiles_transformer': SmilesToMolTransformer(),\n",
" 'pipe': Pipeline(steps=[('mol_transformer', MorganFingerprintTransformer()),\n",
" ('Regressor', Ridge())]),\n",
" 'smiles_transformer__n_jobs': None,\n",
" 'smiles_transformer__safe_inference_mode': False,\n",
" 'pipe__memory': None,\n",
" 'pipe__steps': [('mol_transformer', MorganFingerprintTransformer()),\n",
" ('Regressor', Ridge())],\n",
" 'pipe__transform_input': None,\n",
" 'pipe__verbose': False,\n",
" 'pipe__mol_transformer': MorganFingerprintTransformer(),\n",
" 'pipe__Regressor': Ridge(),\n",
" 'pipe__mol_transformer__fpSize': 2048,\n",
" 'pipe__mol_transformer__n_jobs': None,\n",
" 'pipe__mol_transformer__radius': 2,\n",
" 'pipe__mol_transformer__safe_inference_mode': False,\n",
" 'pipe__mol_transformer__useBondTypes': True,\n",
" 'pipe__mol_transformer__useChirality': False,\n",
" 'pipe__mol_transformer__useCounts': False,\n",
" 'pipe__mol_transformer__useFeatures': False,\n",
" 'pipe__Regressor__alpha': 1.0,\n",
" 'pipe__Regressor__copy_X': True,\n",
" 'pipe__Regressor__fit_intercept': True,\n",
" 'pipe__Regressor__max_iter': None,\n",
" 'pipe__Regressor__positive': False,\n",
" 'pipe__Regressor__random_state': None,\n",
" 'pipe__Regressor__solver': 'auto',\n",
" 'pipe__Regressor__tol': 0.0001}"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"smiles_pipe.get_params()"
]
}
],
"metadata": {
"jupytext": {
"formats": "docs//notebooks//ipynb,docs//notebooks//scripts//py:percent"
},
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
================================================
FILE: docs/notebooks/04_standardizer.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"id": "095e3de9",
"metadata": {},
"source": [
"# Molecule standardization\n",
"When building machine learning models of molecules, it is important to standardize the molecules. We often don't want different predictions just because things are drawn in slightly different forms, such as protonated or deprotanted carboxylic acids. Scikit-mol provides a very basic standardize transformer based on the molvs implementation in RDKit"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "d40bdabe",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:39.191239Z",
"iopub.status.busy": "2025-05-08T16:22:39.189891Z",
"iopub.status.idle": "2025-05-08T16:22:40.514182Z",
"shell.execute_reply": "2025-05-08T16:22:40.512920Z"
}
},
"outputs": [],
"source": [
"from rdkit import Chem\n",
"from scikit_mol.standardizer import Standardizer\n",
"from scikit_mol.fingerprints import MorganFingerprintTransformer\n",
"from scikit_mol.conversions import SmilesToMolTransformer\n",
"from sklearn.pipeline import make_pipeline\n",
"from sklearn.linear_model import Ridge"
]
},
{
"cell_type": "markdown",
"id": "1f739296",
"metadata": {},
"source": [
"For demonstration let's create some molecules with different protonation states. The two first molecules are Benzoic acid and Sodium benzoate."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "5a45dfd5",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:40.518530Z",
"iopub.status.busy": "2025-05-08T16:22:40.517654Z",
"iopub.status.idle": "2025-05-08T16:22:40.537037Z",
"shell.execute_reply": "2025-05-08T16:22:40.535847Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"array([], dtype=object)"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"array([], dtype=object)"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"smiles_strings = (\n",
" \"c1ccccc1C(=O)[OH]\",\n",
" \"c1ccccc1C(=O)[O-].[Na+]\",\n",
" \"CC[NH+](C)C\",\n",
" \"CC[N+](C)(C)C\",\n",
" \"[O-]CC(C(=O)[O-])C[NH+](C)C\",\n",
" \"[O-]CC(C(=O)[O-])C[N+](C)(C)C\",\n",
")\n",
"\n",
"smi2mol = SmilesToMolTransformer()\n",
"\n",
"mols = smi2mol.transform(smiles_strings)\n",
"for mol in mols[0:2]:\n",
" display(mol)"
]
},
{
"cell_type": "markdown",
"id": "1974e56a",
"metadata": {},
"source": [
"We can simply use the transformer directly and get a list of standardized molecules"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "d13141c6",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:40.540032Z",
"iopub.status.busy": "2025-05-08T16:22:40.539703Z",
"iopub.status.idle": "2025-05-08T16:22:40.560979Z",
"shell.execute_reply": "2025-05-08T16:22:40.560007Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"array([['O=C(O)c1ccccc1'],\n",
" ['O=C(O)c1ccccc1'],\n",
" ['CCN(C)C'],\n",
" ['CC[N+](C)(C)C'],\n",
" ['CN(C)CC(CO)C(=O)O'],\n",
" ['C[N+](C)(C)CC(CO)C(=O)[O-]']], dtype='\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
SMILES
\n",
"
y
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
CN(C)(C)(C)
\n",
"
7.18046
\n",
"
\n",
" \n",
"
\n",
""
],
"text/plain": [
" SMILES y\n",
"0 CN(C)(C)(C) 7.18046"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"smileschecker.errors"
]
},
{
"cell_type": "markdown",
"id": "c2ce2677",
"metadata": {},
"source": [
"The checker can also be used only on X"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "84db07cc",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:43.339302Z",
"iopub.status.busy": "2025-05-08T16:22:43.338668Z",
"iopub.status.idle": "2025-05-08T16:22:43.391019Z",
"shell.execute_reply": "2025-05-08T16:22:43.389989Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Error in parsing 1 SMILES. Unparsable SMILES can be found in self.errors\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"[18:22:43] Explicit valence for atom # 1 N, 4, is greater than permitted\n"
]
},
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
SMILES
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
CN(C)(C)(C)
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" SMILES\n",
"0 CN(C)(C)(C)"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"smiles_list_valid, X_errors = smileschecker.sanitize(list(data.SMILES))\n",
"smileschecker.errors"
]
}
],
"metadata": {
"jupytext": {
"formats": "docs//notebooks//ipynb,docs//notebooks//scripts//py:percent"
},
"kernelspec": {
"display_name": "Python 3.9.4 ('rdkit')",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
================================================
FILE: docs/notebooks/06_hyperparameter_tuning.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"id": "f0b0cc54",
"metadata": {},
"source": [
"# Full example: Hyperparameter tuning\n",
"\n",
"first some imports of the usual suspects: RDKit, pandas, matplotlib, numpy and sklearn. New kid on the block is scikit-mol"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "51aa3d62",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:44.604531Z",
"iopub.status.busy": "2025-05-08T16:22:44.604218Z",
"iopub.status.idle": "2025-05-08T16:22:46.163842Z",
"shell.execute_reply": "2025-05-08T16:22:46.162418Z"
}
},
"outputs": [],
"source": [
"import os\n",
"import rdkit\n",
"from rdkit import Chem\n",
"from rdkit.Chem import PandasTools\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"from time import time\n",
"import numpy as np\n",
"from sklearn.pipeline import Pipeline, make_pipeline\n",
"from sklearn.linear_model import Ridge\n",
"from sklearn.model_selection import train_test_split\n",
"from scikit_mol.fingerprints import MorganFingerprintTransformer\n",
"from scikit_mol.conversions import SmilesToMolTransformer"
]
},
{
"cell_type": "markdown",
"id": "e07990d0",
"metadata": {},
"source": [
"We will need some data. There is a dataset with the SLC6A4 active compounds from ExcapeDB on Zenodo. The scikit-mol project uses a subset of this for testing, and the samples there has been specially selected to give good results in testing (it should therefore be used for any production modelling). If full_set is false, the fast subset will be used, and otherwise the full dataset will be downloaded if needed."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "adbc1868",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:46.167928Z",
"iopub.status.busy": "2025-05-08T16:22:46.166905Z",
"iopub.status.idle": "2025-05-08T16:22:46.173404Z",
"shell.execute_reply": "2025-05-08T16:22:46.172138Z"
}
},
"outputs": [],
"source": [
"full_set = False\n",
"\n",
"if full_set:\n",
" csv_file = \"SLC6A4_active_excape_export.csv\"\n",
" if not os.path.exists(csv_file):\n",
" import urllib.request\n",
"\n",
" url = \"https://ndownloader.figshare.com/files/25747817\"\n",
" urllib.request.urlretrieve(url, csv_file)\n",
"else:\n",
" csv_file = \"../../tests/data/SLC6A4_active_excapedb_subset.csv\""
]
},
{
"cell_type": "markdown",
"id": "d2ce3c7f",
"metadata": {},
"source": [
"The CSV data is loaded into a Pandas dataframe and the PandasTools utility from RDKit is used to add a column with RDKit molecules"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "9a283f12",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:46.177164Z",
"iopub.status.busy": "2025-05-08T16:22:46.176440Z",
"iopub.status.idle": "2025-05-08T16:22:46.233488Z",
"shell.execute_reply": "2025-05-08T16:22:46.232374Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 out of 200 SMILES failed in conversion\n"
]
}
],
"source": [
"data = pd.read_csv(csv_file)\n",
"\n",
"PandasTools.AddMoleculeColumnToFrame(data, smilesCol=\"SMILES\")\n",
"print(f\"{data.ROMol.isna().sum()} out of {len(data)} SMILES failed in conversion\")"
]
},
{
"cell_type": "markdown",
"id": "e245e989",
"metadata": {},
"source": [
"We use the train_test_split to, well, split the dataframe's molecule columns and pXC50 column into lists for train and testing"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "303b83de",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:46.236917Z",
"iopub.status.busy": "2025-05-08T16:22:46.236251Z",
"iopub.status.idle": "2025-05-08T16:22:46.243264Z",
"shell.execute_reply": "2025-05-08T16:22:46.242175Z"
},
"lines_to_next_cell": 2
},
"outputs": [],
"source": [
"mol_list_train, mol_list_test, y_train, y_test = train_test_split(\n",
" data.ROMol, data.pXC50, random_state=42\n",
")"
]
},
{
"cell_type": "markdown",
"id": "56247c3b",
"metadata": {},
"source": [
"We will standardize the molecules before modelling. This is best done before the hyperparameter optimization of the featurization with the scikit-mol transformer and regression modelling, as the standardization is otherwise done for every loop in the hyperparameter optimization, which will make it take longer time."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "1383d0fc",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:46.247777Z",
"iopub.status.busy": "2025-05-08T16:22:46.246787Z",
"iopub.status.idle": "2025-05-08T16:22:46.614634Z",
"shell.execute_reply": "2025-05-08T16:22:46.613399Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
}
],
"source": [
"# Probably the recommended way would be to prestandardize the data if there's no changes to the transformer,\n",
"# and then add the standardizer in the inference pipeline.\n",
"\n",
"from scikit_mol.standardizer import Standardizer\n",
"\n",
"standardizer = Standardizer()\n",
"mol_list_std_train = standardizer.transform(mol_list_train)"
]
},
{
"cell_type": "markdown",
"id": "0775d395",
"metadata": {},
"source": [
"A simple pipeline with a MorganTransformer and a Ridge() regression for demonstration."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "51c74711",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:46.618057Z",
"iopub.status.busy": "2025-05-08T16:22:46.617207Z",
"iopub.status.idle": "2025-05-08T16:22:46.622371Z",
"shell.execute_reply": "2025-05-08T16:22:46.621207Z"
},
"lines_to_next_cell": 2
},
"outputs": [],
"source": [
"moltransformer = MorganFingerprintTransformer()\n",
"regressor = Ridge()\n",
"\n",
"optimization_pipe = make_pipeline(moltransformer, regressor)"
]
},
{
"cell_type": "markdown",
"id": "8221a682",
"metadata": {},
"source": [
"For hyperparameter optimization we import the RandomizedSearchCV class from Scikit-Learn. It will try different random combinations of settings and use internal cross-validation to find the best model. In the end, it will fit the best found parameters on the full set. We also import loguniform, to get a better sampling of some of the parameters."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "4c6b833f",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:46.625354Z",
"iopub.status.busy": "2025-05-08T16:22:46.625058Z",
"iopub.status.idle": "2025-05-08T16:22:46.629915Z",
"shell.execute_reply": "2025-05-08T16:22:46.628829Z"
},
"title": "Now hyperparameter tuning"
},
"outputs": [],
"source": [
"from sklearn.model_selection import RandomizedSearchCV\n",
"\n",
"# from sklearn.utils.fixes import loguniform\n",
"from scipy.stats import loguniform"
]
},
{
"cell_type": "markdown",
"id": "6b9d4576",
"metadata": {},
"source": [
"With the pipelines, getting the names of the parameters to tune is a bit more tricky, as they are concatenations of the name of the step and the parameter with double underscores in between. We can get the available parameters from the pipeline with the get_params() method, and select the parameters we want to change from there."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "0af1003b",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:46.633716Z",
"iopub.status.busy": "2025-05-08T16:22:46.632911Z",
"iopub.status.idle": "2025-05-08T16:22:46.641844Z",
"shell.execute_reply": "2025-05-08T16:22:46.640881Z"
},
"title": "Which keys do we have?"
},
"outputs": [
{
"data": {
"text/plain": [
"dict_keys(['memory', 'steps', 'transform_input', 'verbose', 'morganfingerprinttransformer', 'ridge', 'morganfingerprinttransformer__fpSize', 'morganfingerprinttransformer__n_jobs', 'morganfingerprinttransformer__radius', 'morganfingerprinttransformer__safe_inference_mode', 'morganfingerprinttransformer__useBondTypes', 'morganfingerprinttransformer__useChirality', 'morganfingerprinttransformer__useCounts', 'morganfingerprinttransformer__useFeatures', 'ridge__alpha', 'ridge__copy_X', 'ridge__fit_intercept', 'ridge__max_iter', 'ridge__positive', 'ridge__random_state', 'ridge__solver', 'ridge__tol'])"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"optimization_pipe.get_params().keys()"
]
},
{
"cell_type": "markdown",
"id": "cb0db6a5",
"metadata": {},
"source": [
"We will tune the regularization strength of the Ridge regressor, and try out different parameters for the Morgan fingerprint, namely the number of bits, the radius of the fingerprint, wheter to use counts or bits and features."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "c2d541b3",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:46.645249Z",
"iopub.status.busy": "2025-05-08T16:22:46.644964Z",
"iopub.status.idle": "2025-05-08T16:22:46.651276Z",
"shell.execute_reply": "2025-05-08T16:22:46.650210Z"
}
},
"outputs": [],
"source": [
"param_dist = {\n",
" \"ridge__alpha\": loguniform(1e-2, 1e3),\n",
" \"morganfingerprinttransformer__fpSize\": [256, 512, 1024, 2048, 4096],\n",
" \"morganfingerprinttransformer__radius\": [1, 2, 3, 4],\n",
" \"morganfingerprinttransformer__useCounts\": [True, False],\n",
" \"morganfingerprinttransformer__useFeatures\": [True, False],\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "2157d154",
"metadata": {
"lines_to_next_cell": 2
},
"source": [
"The report function was taken from [this example](https://scikit-learn.org/stable/auto_examples/model_selection/plot_randomized_search.html#sphx-glr-auto-examples-model-selection-plot-randomized-search-py) from the scikit learn documentation."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "f2c91783",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:46.655212Z",
"iopub.status.busy": "2025-05-08T16:22:46.654913Z",
"iopub.status.idle": "2025-05-08T16:22:46.662196Z",
"shell.execute_reply": "2025-05-08T16:22:46.661226Z"
},
"title": "From https://scikit-learn.org/stable/auto_examples/model_selection/plot_randomized_search.html#sphx-glr-auto-examples-model-selection-plot-randomized-search-py"
},
"outputs": [],
"source": [
"# Utility function to report best scores\n",
"def report(results, n_top=3):\n",
" for i in range(1, n_top + 1):\n",
" candidates = np.flatnonzero(results[\"rank_test_score\"] == i)\n",
" for candidate in candidates:\n",
" print(\"Model with rank: {0}\".format(i))\n",
" print(\n",
" \"Mean validation score: {0:.3f} (std: {1:.3f})\".format(\n",
" results[\"mean_test_score\"][candidate],\n",
" results[\"std_test_score\"][candidate],\n",
" )\n",
" )\n",
" print(\"Parameters: {0}\".format(results[\"params\"][candidate]))\n",
" print(\"\")"
]
},
{
"cell_type": "markdown",
"id": "469691f4",
"metadata": {},
"source": [
"We will do 25 tries of random parameter sets, and see what comes out as the best one. If you are using the small example dataset, this should take some second, but may take some minutes with the full set."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "79a70a0f",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:46.665390Z",
"iopub.status.busy": "2025-05-08T16:22:46.665100Z",
"iopub.status.idle": "2025-05-08T16:22:49.120359Z",
"shell.execute_reply": "2025-05-08T16:22:49.119269Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Runtime: 2.45 for 25 iterations)\n"
]
}
],
"source": [
"n_iter_search = 25\n",
"random_search = RandomizedSearchCV(\n",
" optimization_pipe, param_distributions=param_dist, n_iter=n_iter_search, cv=3\n",
")\n",
"t0 = time()\n",
"random_search.fit(mol_list_std_train, y_train.values)\n",
"t1 = time()\n",
"\n",
"print(f\"Runtime: {t1-t0:0.2F} for {n_iter_search} iterations)\")"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "b6160cb3",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:49.124324Z",
"iopub.status.busy": "2025-05-08T16:22:49.123579Z",
"iopub.status.idle": "2025-05-08T16:22:49.130023Z",
"shell.execute_reply": "2025-05-08T16:22:49.128965Z"
},
"lines_to_next_cell": 0
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model with rank: 1\n",
"Mean validation score: 0.459 (std: 0.117)\n",
"Parameters: {'morganfingerprinttransformer__fpSize': 1024, 'morganfingerprinttransformer__radius': 3, 'morganfingerprinttransformer__useCounts': False, 'morganfingerprinttransformer__useFeatures': True, 'ridge__alpha': np.float64(11.211371939288233)}\n",
"\n",
"Model with rank: 2\n",
"Mean validation score: 0.427 (std: 0.130)\n",
"Parameters: {'morganfingerprinttransformer__fpSize': 512, 'morganfingerprinttransformer__radius': 2, 'morganfingerprinttransformer__useCounts': True, 'morganfingerprinttransformer__useFeatures': False, 'ridge__alpha': np.float64(22.96332964984786)}\n",
"\n",
"Model with rank: 3\n",
"Mean validation score: 0.426 (std: 0.166)\n",
"Parameters: {'morganfingerprinttransformer__fpSize': 4096, 'morganfingerprinttransformer__radius': 2, 'morganfingerprinttransformer__useCounts': True, 'morganfingerprinttransformer__useFeatures': False, 'ridge__alpha': np.float64(23.874114087368742)}\n",
"\n"
]
}
],
"source": [
"report(random_search.cv_results_)"
]
},
{
"cell_type": "markdown",
"id": "9a2ea219",
"metadata": {},
"source": [
"It can be interesting to see what combinations of hyperparameters gave good results for the cross-validation. Usually the number of bits are in the high end and radius is 2 to 4. But this can vary a bit, as we do a small number of tries for this demo. More extended search with more iterations could maybe find even better and more consistent. solutions"
]
},
{
"cell_type": "markdown",
"id": "6cf91582",
"metadata": {},
"source": [
"Let's see if standardization had any influence on this dataset. We build an inference pipeline that includes the standardization object and the best estimator, and run the best estimator directly on the list of test molecules"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "4daaf106",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:49.133255Z",
"iopub.status.busy": "2025-05-08T16:22:49.132589Z",
"iopub.status.idle": "2025-05-08T16:22:49.294436Z",
"shell.execute_reply": "2025-05-08T16:22:49.293304Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"No Standardization 0.4921\n",
"With Standardization 0.4921\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
}
],
"source": [
"inference_pipe = make_pipeline(standardizer, random_search.best_estimator_)\n",
"\n",
"print(\n",
" f\"No Standardization {random_search.best_estimator_.score(mol_list_test, y_test):0.4F}\"\n",
")\n",
"print(f\"With Standardization {inference_pipe.score(mol_list_test, y_test):0.4F}\")"
]
},
{
"cell_type": "markdown",
"id": "2d31c059",
"metadata": {
"lines_to_next_cell": 0,
"title": "Building an inference pipeline, it appears our test-data was pretty standard"
},
"source": [
"We see that the dataset already appeared to be in forms that are similar to the ones coming from the standardization.\n",
"\n",
"Interestingly the test-set performance often seem to be better than the CV performance during the hyperparameter search. This may be due to the model being refit at the end of the search to the whole training dataset, as the refit parameter on the randomized_search object by default is true. The final model is thus fitted on more data than the individual models during training.\n",
"\n",
"To demonstrate the effect of standartization we can see the difference if we challenge the predictor with different forms of benzoic acid and benzoates."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "92105568",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:49.297625Z",
"iopub.status.busy": "2025-05-08T16:22:49.297285Z",
"iopub.status.idle": "2025-05-08T16:22:49.318086Z",
"shell.execute_reply": "2025-05-08T16:22:49.316957Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Predictions with no standardization: [6.36710496 6.49711427 6.49711427 6.28330625 6.72697401]\n",
"Predictions with standardization: [6.36710496 6.36710496 6.36710496 6.36710496 6.36710496]\n"
]
}
],
"source": [
"# Intergrating the Standardizer and challenge it with some different forms and salts of benzoic acid\n",
"smiles_list = [\n",
" \"c1ccccc1C(=O)[OH]\",\n",
" \"c1ccccc1C(=O)[O-]\",\n",
" \"c1ccccc1C(=O)[O-].[Na+]\",\n",
" \"c1ccccc1C(=O)[O][Na]\",\n",
" \"c1ccccc1C(=O)[O-].C[N+](C)C\",\n",
"]\n",
"mols_list = [Chem.MolFromSmiles(smiles) for smiles in smiles_list]\n",
"\n",
"print(\n",
" f\"Predictions with no standardization: {random_search.best_estimator_.predict(mols_list)}\"\n",
")\n",
"print(f\"Predictions with standardization: {inference_pipe.predict(mols_list)}\")"
]
},
{
"cell_type": "markdown",
"id": "9d196197",
"metadata": {},
"source": [
"Without standardization we get variation in the predictions, but with the standardization object in place, we get the same results. If you want a model that gives different predictions for the different forms, either the standardization need to be removed or the settings changed.\n",
"\n",
"From here it should be easy to save the model using pickle, so that it can be loaded and used in other python projects. The pipeline carries both the standardization, the featurization and the prediction in one, easy to reuse object. If you want the model to be able to predict directly from SMILES strings, check out the SmilesToMol class, which is also available in Scikit-Mol :-)\n"
]
},
{
"cell_type": "markdown",
"id": "824ebc99",
"metadata": {},
"source": []
}
],
"metadata": {
"jupytext": {
"formats": "docs//notebooks//ipynb,docs//notebooks//scripts//py:percent"
},
"kernelspec": {
"display_name": "Python 3.9.4 ('rdkit')",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
================================================
FILE: docs/notebooks/07_parallel_transforms.ipynb
================================================
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "6f68fb8e",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "87ed8373",
"metadata": {},
"source": [
"# Parallel calculations of transforms\n",
"\n",
"Scikit-mol supports parallel calculations of fingerprints and descriptors. This feature can be activated and configured using the `n_jobs` parameter or the `.n_jobs` attribute after object instantiation.\n",
"\n",
"To begin, let's import the necessary libraries: RDKit and pandas. And of course, we'll also need to import scikit-mol, which is the new kid on the block."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "dac6956a",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:27:38.302600Z",
"iopub.status.busy": "2024-11-24T09:27:38.302116Z",
"iopub.status.idle": "2024-11-24T09:27:39.171522Z",
"shell.execute_reply": "2024-11-24T09:27:39.170882Z"
}
},
"outputs": [],
"source": [
"import pathlib\n",
"import time\n",
"\n",
"import pandas as pd\n",
"from rdkit.Chem import PandasTools\n",
"\n",
"from scikit_mol.conversions import SmilesToMolTransformer\n",
"from scikit_mol.descriptors import MolecularDescriptorTransformer\n",
"from scikit_mol.fingerprints import MorganFingerprintTransformer"
]
},
{
"cell_type": "markdown",
"id": "7c2a81f2",
"metadata": {},
"source": [
"## Obtaining the Data\n",
"\n",
"We'll need some data to work with, so we'll use a dataset of SLC6A4 active compounds from ExcapeDB that is available on Zenodo. Scikit-mol uses a subset of this dataset for testing purposes, and the samples have been specially selected to provide good results in testing. Note: This dataset should never be used for production modeling.\n",
"\n",
"In the code below, you can set full_set to True to download the full dataset. Otherwise, the smaller dataset will be used."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "f64c418f",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:27:39.174368Z",
"iopub.status.busy": "2024-11-24T09:27:39.174075Z",
"iopub.status.idle": "2024-11-24T09:27:39.177863Z",
"shell.execute_reply": "2024-11-24T09:27:39.177305Z"
}
},
"outputs": [],
"source": [
"full_set = False\n",
"\n",
"if full_set:\n",
" csv_file = \"SLC6A4_active_excape_export.csv\"\n",
" if not pathlib.Path(csv_file).exists():\n",
" import urllib.request\n",
"\n",
" url = \"https://ndownloader.figshare.com/files/25747817\"\n",
" urllib.request.urlretrieve(url, csv_file)\n",
"else:\n",
" csv_file = \"../tests/data/SLC6A4_active_excapedb_subset.csv\""
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "0eabd800",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:27:39.180191Z",
"iopub.status.busy": "2024-11-24T09:27:39.179937Z",
"iopub.status.idle": "2024-11-24T09:27:39.221096Z",
"shell.execute_reply": "2024-11-24T09:27:39.220386Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 out of 200 SMILES failed in conversion\n"
]
}
],
"source": [
"data = pd.read_csv(csv_file)\n",
"\n",
"PandasTools.AddMoleculeColumnToFrame(data, smilesCol=\"SMILES\")\n",
"print(f\"{data.ROMol.isna().sum()} out of {len(data)} SMILES failed in conversion\")"
]
},
{
"cell_type": "markdown",
"id": "4144946e",
"metadata": {},
"source": [
"## Evaluating the Impact of Parallelism on Transformations\n",
"\n",
"Let's start by creating a baseline for our calculations without using parallelism."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "a7f66af7",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:27:39.223702Z",
"iopub.status.busy": "2024-11-24T09:27:39.223459Z",
"iopub.status.idle": "2024-11-24T09:27:39.228461Z",
"shell.execute_reply": "2024-11-24T09:27:39.227977Z"
},
"title": "A demonstration of the speedup that can be had for the descriptor transformer"
},
"outputs": [],
"source": [
"transformer = MolecularDescriptorTransformer(n_jobs=1)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "a03bc824",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:27:39.230911Z",
"iopub.status.busy": "2024-11-24T09:27:39.230692Z",
"iopub.status.idle": "2024-11-24T09:27:41.368180Z",
"shell.execute_reply": "2024-11-24T09:27:41.367438Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/scikit-mol/.venv/lib/python3.9/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Calculation time on dataset of size 200 with parallel=1:\t2.10 seconds\n"
]
}
],
"source": [
"def test_transformer(transformer):\n",
" t0 = time.time()\n",
" transformer.transform(data.ROMol)\n",
" t = time.time() - t0\n",
" print(\n",
" f\"Calculation time on dataset of size {len(data)} with n_jobs={transformer.n_jobs}:\\t{t:0.2F} seconds\"\n",
" )\n",
"\n",
"\n",
"test_transformer(transformer)"
]
},
{
"cell_type": "markdown",
"id": "d304d675",
"metadata": {},
"source": [
"\n",
"Let's see if parallelism can help us speed up our transformations."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "c80388e6",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:27:41.370886Z",
"iopub.status.busy": "2024-11-24T09:27:41.370638Z",
"iopub.status.idle": "2024-11-24T09:27:42.384085Z",
"shell.execute_reply": "2024-11-24T09:27:42.383188Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/scikit-mol/.venv/lib/python3.9/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Calculation time on dataset of size 200 with parallel=2:\t2.19 seconds\n"
]
}
],
"source": [
"transformer = MolecularDescriptorTransformer(n_jobs=2)\n",
"test_transformer(transformer)"
]
},
{
"cell_type": "markdown",
"id": "731bd13a",
"metadata": {},
"source": [
"We've seen that parallelism can help speed up our transformations, with the degree of speedup depending on the number of CPU cores available. However, it's worth noting that there may be some overhead associated with the process of splitting the dataset, pickling objects and functions, and passing them to the parallel child processes. As a result, it may not always be worthwhile to use parallelism, particularly for smaller datasets or certain types of fingerprints.\n",
"\n",
"It's also worth noting that there are different methods for creating the child processes, with the default method on Linux being 'fork', while on Mac and Windows it's 'spawn'. The code we're using has been tested on Linux using the 'fork' method.\n",
"\n",
"Now, let's see how parallelism impacts another type of transformer."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "ef6d2b0c",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:27:42.387160Z",
"iopub.status.busy": "2024-11-24T09:27:42.386886Z",
"iopub.status.idle": "2024-11-24T09:27:42.484867Z",
"shell.execute_reply": "2024-11-24T09:27:42.484222Z"
},
"lines_to_next_cell": 2,
"title": "Some of the benchmarking plots"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Calculation time on dataset of size 200 with parallel=1:\t0.03 seconds\n",
"Calculation time on dataset of size 200 with parallel=2:\t0.08 seconds\n"
]
}
],
"source": [
"transformer = MorganFingerprintTransformer(n_jobs=1)\n",
"test_transformer(transformer)\n",
"transformer.n_jobs = 2\n",
"test_transformer(transformer)"
]
},
{
"cell_type": "markdown",
"id": "2aac85b1",
"metadata": {},
"source": [
"Interestingly, we observed that parallelism actually took longer to calculate the fingerprints in some cases, which is a perfect illustration of the overhead issue associated with parallelism. Generally, the faster the fingerprint calculation in itself, the larger the dataset needs to be for parallelism to be worthwhile. For example, the Descriptor transformer, which is one of the slowest, can benefit even for smaller datasets, while for faster fingerprint types like Morgan, Atompairs, and Topological Torsion fingerprints, the dataset needs to be larger.\n",
"\n",
"\n",
"\n",
"We've also included a series of plots below, showing the speedup over serial for different numbers of cores used for different dataset sizes. These timings were taken on a 16 core machine (32 Hyperthreads). Only the largest datasets (>10,000 samples) would make it worthwhile to parallelize Morgan, Atompairs, and Topological Torsions. SECfingerprint, MACCS keys, and RDKitFP are intermediate and would benefit from parallelism when the dataset size is larger, say >500. Descriptors, on the other hand, benefit almost immediately even for the smallest datasets (>100 samples).\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "0913a9f4",
"metadata": {},
"source": [
"## Performance heatmaps\n",
"\n",
"Multiprocessing performance is highly dependent on CPU performance, type of the function and the size of the dataset. To help users understand the performance of their system, we have created a series of heatmaps showing the speedup of different transformers for different dataset sizes and number of cores. The heatmaps are based on the same data as the plots above.\n",
"If you what to test the performance of your system, you can run the code below."
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "0b353728",
"metadata": {},
"outputs": [],
"source": [
"from rdkit import Chem\n",
"\n",
"from scikit_mol.fingerprints import (\n",
" AtomPairFingerprintTransformer,\n",
" AvalonFingerprintTransformer,\n",
" MHFingerprintTransformer,\n",
" MorganFingerprintTransformer,\n",
" RDKitFingerprintTransformer,\n",
" TopologicalTorsionFingerprintTransformer,\n",
")\n",
"from scikit_mol.plotting import ParallelTester, plot_heatmap\n",
"from scikit_mol.standardizer import Standardizer\n",
"\n",
"mols = [Chem.MolFromSmiles(\"CCCCCCCCBr\")] * 100000\n",
"transformers = [\n",
" Standardizer(),\n",
" MorganFingerprintTransformer(),\n",
" MolecularDescriptorTransformer(),\n",
" MHFingerprintTransformer(),\n",
" AtomPairFingerprintTransformer(),\n",
" AvalonFingerprintTransformer(),\n",
" RDKitFingerprintTransformer(),\n",
" TopologicalTorsionFingerprintTransformer(),\n",
"]"
]
},
{
"cell_type": "markdown",
"id": "47991a4f",
"metadata": {},
"source": [
"`ParallelTester` accept the following parameters:\n",
"- `transformer` - the transformer to test\n",
"- `mols` - the dataset to test\n",
"- `n_mols` - the number of molecules to test on (the largest number should be less than or equal to the number of molecules in `mols`)\n",
"- `n_cores` - the number of cores to test on (the largest number should be less than or equal to the number of cores in your system)\n",
"- `backend` - the backend to use for multiprocessing (default is `loky`, see [joblib documentation](https://joblib.readthedocs.io/en/latest/parallel.html) for more options)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "fa00f0eb",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
10
\n",
"
100
\n",
"
100
\n",
"
1000
\n",
"
10000
\n",
"
100000
\n",
"
\n",
" \n",
" \n",
"
\n",
"
1
\n",
"
0.002394
\n",
"
0.003997
\n",
"
0.003997
\n",
"
0.031515
\n",
"
0.479826
\n",
"
3.228737
\n",
"
\n",
"
\n",
"
2
\n",
"
0.012707
\n",
"
1.278691
\n",
"
1.278691
\n",
"
1.246285
\n",
"
1.507089
\n",
"
3.614131
\n",
"
\n",
"
\n",
"
4
\n",
"
1.238397
\n",
"
1.330802
\n",
"
1.330802
\n",
"
1.20337
\n",
"
1.389253
\n",
"
2.891467
\n",
"
\n",
"
\n",
"
8
\n",
"
1.657188
\n",
"
1.669887
\n",
"
1.669887
\n",
"
1.601371
\n",
"
1.635777
\n",
"
2.541485
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" 10 100 100 1000 10000 100000\n",
"1 0.002394 0.003997 0.003997 0.031515 0.479826 3.228737\n",
"2 0.012707 1.278691 1.278691 1.246285 1.507089 3.614131\n",
"4 1.238397 1.330802 1.330802 1.20337 1.389253 2.891467\n",
"8 1.657188 1.669887 1.669887 1.601371 1.635777 2.541485"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"transformer = MorganFingerprintTransformer()\n",
"df = ParallelTester(transformer, mols).test()\n",
"df"
]
},
{
"cell_type": "markdown",
"id": "71725395",
"metadata": {},
"source": [
"Resulting df have one row for each `n_jobs` and one row for each `n_mols`. Results can be plotted as a heatmap using the `plot_heatmap` method."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "6e352da5",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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o3H5eTo8bW9vj82bN0Mmk6l8nT9/Pi+rp7Hk5GTcuHEDN27cAAA8efIEN27cwLNnzwC8W9X0008/yfN/++23ePz4MWbOnIn79+9j3bp12LdvH7p27SrP061bN2zevBnbt2/HvXv3MHHiRKSkpCj95fA1YTvmHrZl7mFb5g62Y+5hW1JWjh49ijt37mgUOUxMTMTdu3dhb2+vcfl5Gmn09PTEuXPn0LJlS5XH1UUh84urV68qzB2YNm0aAKBFixaYMGECYmJiEBUVJT9evHhxzJs3D1OnTsXq1atha2uL4OBg+dYHANCoUSPExcVhwYIFiImJgaurKxYsWKA0UflrwnbMPWzL3MO2zB1sx9zDttSO/LQJd2JiokIE8P79+7h48SIsLS1RsmRJBAUF4cmTJ1i5cqXCeUuXLkWNGjXg7u6uVObIkSPRvHlzODg44OnTpwgODoauri46deqkcb0kIg97ZcePH0dSUhIaNWqk8nhSUhIiIiLg6+ubo3Lz+/A0ERERKTM0NMyza5/3nqG1sqv8PVx9pvccOXIE9erVU0rv0aMHQkNDERAQgMjISBw5ckR+LCEhAfb29pg9ezb69OmjdG7Hjh1x7NgxxMbGwtraGrVr18Zvv/0GZ2dnjeuVp51GbWGnkYiI6MuTl53GC3Vmaa3syseGaq3szyn/xGKJiIiIKN/iYwSJiIiowMtPcxrzK3YaiYiIqMDLT8+ezq/YQkRERESkFiONREREVOBxeFo9thARERERqcVIIxERERV4jDSqxxYiIiIiIrUYaSQiIqICj6un1WMLEREREZFajDQSERFRgcc5jeqxhYiIiIhILUYaiYiIqMBjpFE9dhqJiIiowONCGPXYQkRERESkFiONREREVOBxeFo9thARERERqcVIIxERERV4El1JXlch32OkkYiIiIjUYqSRiIiICjzOaVSPLUREREREajHSSERERAUeI43qsdNIREREBR4391aPLUREREREajHSSERERAUeh6fVYwsRERERkVqMNBIREVGBxzmN6rGFiIiIiEgtRhqJiIiowOOcRvXYQkRERESkFiONREREVOBJdBhHU4edRiIiIiJdSV7XIN9jt5qIiIiI1GKkkYiIiAo8Dk+rxxYiIiIiIrUYaSQiIqICj5t7q8cWIiIiIiK1GGkkIiKiAo9zGtVjCxERERGRWow0EhER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",
"text/plain": [
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plot_heatmap(df, \"Morgan Fingerprint\")"
]
},
{
"cell_type": "markdown",
"id": "0972c254",
"metadata": {},
"source": [
"By default the time is normalized to the time of the serial calculation. Such as a value of 2 means that the calculation took twice as long as the serial calculation and values below 1 means that the calculation was faster than the serial calculation.\n",
"If you want to see the absolute time, you can set `normalize=False`."
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "c99487eb",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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SmVt2rRBmzZt/vO52SkkIiKib15+yRRqEjuFRERE9M1T5+LVXwu2ABERERExU0hERETE4WNmComIiIgIzBQSERERcU4hmCkkIiIiIjBTSERERMQ5hWCmkIiIiIjATCERERERJFrMk7FTSERERKQt0XQEGsduMRERERExU0hERETE4WNmComIiIgIzBQSERERcfFqMFNIRERERGCmkIiIiIhzCsFMIRERERGBmUIiIiIirlMIdgqJiIiIOHwMDh8TEREREZgpJCIiIuKSNGCmkIiIiIjATCERERER5xSCmUIiIiIiAjOFRERERFySBswUEhERERGYKSQiIiLinEKwU0hERETEJWnA4WMiIiIiAjOF9Ambpi7UdAhECjJkaZoOocCwNyqn6RAKjPW9ftV0CAWCjwbPLdHijSbMFBIRERERM4VERERE4JxCZgqJiIiIiJlCIiIiIi5JA2YKiYiIiAjMFBIRERFxnUKwU0hERETEJWnA4WMiIiIiAjOFRERERABvNGGmkIiIiIiYKSQiIiLijSZgppCIiIiIwEwhERERERevBjOFRERERARmComIiIgg0eY6hewUEhEREXH4mMPHRERERMRMIRERERGXpAEzhUREREQEZgqJiIiIINHijSbMFBIRERERM4VEREREnFPITCERERFRvhEYGIhKlSrBxMQEtra2aN68Oe7cuZPtPkFBQZBIJAovfX39XJ+bnUIiIiIiLYn6Xrlw8uRJDBgwABcuXMDhw4eRnp6OevXqISkpKdv9TE1N8fLlS/nr8ePHuW4CDh8TERHRN08iyR83mhw4cEDhfVBQEGxtbXHp0iVUr149y/0kEgns7Oz+07mZKSQiIiJSo9TUVLx580bhlZqamqN94+PjAQCWlpbZ1ktMTISjoyOKFSuGgIAA3LhxI9dxslNIREREpMbh48DAQJiZmSm8AgMDPxmSTCbD0KFD4evrC09Pzyzrubq6YtWqVdi5cyfWrVsHmUyGqlWr4tmzZ7lqAg4fExEREanRmDFjMHz4cIUyqVT6yf0GDBiA69ev48yZM9nW8/HxgY+Pj/x91apV4ebmhmXLlmHSpEk5jpOdQiIiIvrmqXPxaqlUmqNO4IcGDhyIPXv24NSpU7C3t8/Vvrq6uihfvjzu37+fq/04fExERESUTwghMHDgQGzfvh3Hjh2Dk5NTro+RkZGB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",
"text/plain": [
"
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from skopt.plots import plot_convergence\n",
"\n",
"plot_convergence(pipe_gp)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "aebdc43d",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"jupytext": {
"formats": "docs//notebooks//ipynb,docs//notebooks//scripts//py:percent"
},
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
================================================
FILE: docs/notebooks/09_Combinatorial_Method_Usage_with_FingerPrint_Transformers.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"id": "0e70fca3",
"metadata": {},
"source": [
"# Example: Using Multiple Different Fingerprint Transformer\n",
"\n",
"In this notebook we will explore how to evaluate the performance of machine learning models depending on different fingerprint transformers (Featurization techniques). This is an example, that you easily could adapt for many different combinations of featurizers, optimization and other modelling techniques.\n",
"\n",
"Following steps will happen:\n",
"* Data Parsing\n",
"* Pipeline Building\n",
"* Training Phase\n",
"* Analysis\n",
"\n",
"Authors: @VincentAlexanderScholz, @RiesBen\n",
"\n",
"## Imports:\n",
"First we will import all the stuff that we will need for our work.\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "b705b5c9",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:50.685069Z",
"iopub.status.busy": "2025-05-08T16:22:50.684787Z",
"iopub.status.idle": "2025-05-08T16:22:52.211375Z",
"shell.execute_reply": "2025-05-08T16:22:52.210158Z"
},
"lines_to_next_cell": 2
},
"outputs": [],
"source": [
"import os\n",
"import numpy as np\n",
"import pandas as pd\n",
"from time import time\n",
"from matplotlib import pyplot as plt\n",
"\n",
"from rdkit.Chem import PandasTools\n",
"\n",
"from sklearn.model_selection import GridSearchCV\n",
"from sklearn.pipeline import Pipeline, make_pipeline\n",
"from sklearn.linear_model import Ridge\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"from scikit_mol import fingerprints"
]
},
{
"cell_type": "markdown",
"id": "2a4eb825",
"metadata": {},
"source": [
"## Get Data:\n",
"In this step we will check if the SLC6A4 data set is already present or needs to be downloaded.\n",
"\n",
"\n",
"**WARNING:** The Dataset is a simple and very well selected"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "34b2618a",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:52.215818Z",
"iopub.status.busy": "2025-05-08T16:22:52.214649Z",
"iopub.status.idle": "2025-05-08T16:22:52.271743Z",
"shell.execute_reply": "2025-05-08T16:22:52.270511Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 out of 200 SMILES failed in conversion\n"
]
}
],
"source": [
"full_set = False\n",
"\n",
"# if not present download example data\n",
"if full_set:\n",
" csv_file = \"SLC6A4_active_excape_export.csv\"\n",
" if not os.path.exists(csv_file):\n",
" import urllib.request\n",
"\n",
" url = \"https://ndownloader.figshare.com/files/25747817\"\n",
" urllib.request.urlretrieve(url, csv_file)\n",
"else:\n",
" csv_file = \"../../tests/data/SLC6A4_active_excapedb_subset.csv\"\n",
"\n",
"# Parse Database\n",
"data = pd.read_csv(csv_file)\n",
"\n",
"PandasTools.AddMoleculeColumnToFrame(data, smilesCol=\"SMILES\")\n",
"print(f\"{data.ROMol.isna().sum()} out of {len(data)} SMILES failed in conversion\")"
]
},
{
"cell_type": "markdown",
"id": "b8dba759",
"metadata": {},
"source": [
"## Build Pipeline:\n",
"In this stage we will build the Pipeline consisting of the featurization part (fingerprint transformers) and the model part (Ridge Regression).\n",
"\n",
"Note that the featurization in this section is a hyperparameter, living in `param_grid`, and the `\"fp_transformer\"` string is just a placeholder, being replaced during pipeline execution.\n",
"\n",
"This way we can define multiple different scenarios in `param_grid`, that allow us to rapidly explore different combinations of settings and methodologies."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "e06042cc",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:52.275673Z",
"iopub.status.busy": "2025-05-08T16:22:52.274777Z",
"iopub.status.idle": "2025-05-08T16:22:52.289345Z",
"shell.execute_reply": "2025-05-08T16:22:52.288093Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"[{'fp_transformer': [MorganFingerprintTransformer(),\n",
" AvalonFingerprintTransformer()],\n",
" 'fp_transformer__fpSize': [256, 512, 1024, 2048, 4096],\n",
" 'regressor__alpha': array([0.1 , 0.325, 0.55 , 0.775, 1. ])},\n",
" {'fp_transformer': [RDKitFingerprintTransformer(),\n",
" AtomPairFingerprintTransformer(),\n",
" MACCSKeysFingerprintTransformer()],\n",
" 'regressor__alpha': array([0.1 , 0.325, 0.55 , 0.775, 1. ])}]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"regressor = Ridge()\n",
"optimization_pipe = Pipeline(\n",
" [\n",
" (\n",
" \"fp_transformer\",\n",
" \"fp_transformer\",\n",
" ), # this is a placeholder for different transformers\n",
" (\"regressor\", regressor),\n",
" ]\n",
")\n",
"\n",
"param_grid = [ # Here pass different Options and Approaches\n",
" {\n",
" \"fp_transformer\": [\n",
" fingerprints.MorganFingerprintTransformer(),\n",
" fingerprints.AvalonFingerprintTransformer(),\n",
" ],\n",
" \"fp_transformer__fpSize\": [2**x for x in range(8, 13)],\n",
" },\n",
" {\n",
" \"fp_transformer\": [\n",
" fingerprints.RDKitFingerprintTransformer(),\n",
" fingerprints.AtomPairFingerprintTransformer(),\n",
" fingerprints.MACCSKeysFingerprintTransformer(),\n",
" ],\n",
" },\n",
"]\n",
"\n",
"global_options = {\n",
" \"regressor__alpha\": np.linspace(0.1, 1, 5),\n",
"}\n",
"\n",
"[params.update(global_options) for params in param_grid]\n",
"\n",
"param_grid"
]
},
{
"cell_type": "markdown",
"id": "521aa24a",
"metadata": {},
"source": [
"## Train Model\n",
"In this section, the combinatorial approaches are trained."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "f1cf66df",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:22:52.293059Z",
"iopub.status.busy": "2025-05-08T16:22:52.292608Z",
"iopub.status.idle": "2025-05-08T16:23:24.403914Z",
"shell.execute_reply": "2025-05-08T16:23:24.402481Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Runtime: 32.10\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
}
],
"source": [
"# Split Data\n",
"mol_list_train, mol_list_test, y_train, y_test = train_test_split(\n",
" data.ROMol, data.pXC50, random_state=0\n",
")\n",
"\n",
"# Define Search Process\n",
"grid = GridSearchCV(optimization_pipe, n_jobs=1, param_grid=param_grid)\n",
"\n",
"# Train\n",
"t0 = time()\n",
"grid.fit(mol_list_train, y_train.values)\n",
"t1 = time()\n",
"\n",
"print(f\"Runtime: {t1-t0:0.2F}\")"
]
},
{
"cell_type": "markdown",
"id": "55aa1549",
"metadata": {},
"source": [
"## Analysis\n",
"\n",
"Now let's investigate our results from the training stage. Which one is the best fingerprint method for this data set? Which parameters are optimal?"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "f80006f8",
"metadata": {
"execution": {
"iopub.execute_input": "2025-05-08T16:23:24.408236Z",
"iopub.status.busy": "2025-05-08T16:23:24.407494Z",
"iopub.status.idle": "2025-05-08T16:23:24.478389Z",
"shell.execute_reply": "2025-05-08T16:23:24.477178Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# plot ALL test score vs. approach\n",
"df = df_training_stats.sort_values(by=\"mean_test_score\")\n",
"\n",
"plt.figure(figsize=[16, 9])\n",
"plt.bar(range(len(df)), df.mean_test_score, yerr=df.std_test_score)\n",
"plt.ylabel(\"mean score\", fontsize=14)\n",
"plt.xticks(range(len(df))[::5], df.param_fp_transformer[::5], rotation=90, fontsize=14)\n",
"plt.title(\"test score vs. approach\", fontsize=18)\n",
"pass"
]
},
{
"cell_type": "markdown",
"id": "f407671c",
"metadata": {},
"source": [
"This file have the following licence:\n",
"\n",
" Apache License\n",
" Version 2.0, January 2004\n",
" http://www.apache.org/licenses/\n",
"\n",
" TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n",
"\n",
" 1. Definitions.\n",
"\n",
" \"License\" shall mean the terms and conditions for use, reproduction,\n",
" and distribution as defined by Sections 1 through 9 of this document.\n",
"\n",
" \"Licensor\" shall mean the copyright owner or entity authorized by\n",
" the copyright owner that is granting the License.\n",
"\n",
" \"Legal Entity\" shall mean the union of the acting entity and all\n",
" other entities that control, are controlled by, or are under common\n",
" control with that entity. For the purposes of this definition,\n",
" \"control\" means (i) the power, direct or indirect, to cause the\n",
" direction or management of such entity, whether by contract or\n",
" otherwise, or (ii) ownership of fifty percent (50%) or more of the\n",
" outstanding shares, or (iii) beneficial ownership of such entity.\n",
"\n",
" \"You\" (or \"Your\") shall mean an individual or Legal Entity\n",
" exercising permissions granted by this License.\n",
"\n",
" \"Source\" form shall mean the preferred form for making modifications,\n",
" including but not limited to software source code, documentation\n",
" source, and configuration files.\n",
"\n",
" \"Object\" form shall mean any form resulting from mechanical\n",
" transformation or translation of a Source form, including but\n",
" not limited to compiled object code, generated documentation,\n",
" and conversions to other media types.\n",
"\n",
" \"Work\" shall mean the work of authorship, whether in Source or\n",
" Object form, made available under the License, as indicated by a\n",
" copyright notice that is included in or attached to the work\n",
" (an example is provided in the Appendix below).\n",
"\n",
" \"Derivative Works\" shall mean any work, whether in Source or Object\n",
" form, that is based on (or derived from) the Work and for which the\n",
" editorial revisions, annotations, elaborations, or other modifications\n",
" represent, as a whole, an original work of authorship. For the purposes\n",
" of this License, Derivative Works shall not include works that remain\n",
" separable from, or merely link (or bind by name) to the interfaces of,\n",
" the Work and Derivative Works thereof.\n",
"\n",
" \"Contribution\" shall mean any work of authorship, including\n",
" the original version of the Work and any modifications or additions\n",
" to that Work or Derivative Works thereof, that is intentionally\n",
" submitted to Licensor for inclusion in the Work by the copyright owner\n",
" or by an individual or Legal Entity authorized to submit on behalf of\n",
" the copyright owner. For the purposes of this definition, \"submitted\"\n",
" means any form of electronic, verbal, or written communication sent\n",
" to the Licensor or its representatives, including but not limited to\n",
" communication on electronic mailing lists, source code control systems,\n",
" and issue tracking systems that are managed by, or on behalf of, the\n",
" Licensor for the purpose of discussing and improving the Work, but\n",
" excluding communication that is conspicuously marked or otherwise\n",
" designated in writing by the copyright owner as \"Not a Contribution.\"\n",
"\n",
" \"Contributor\" shall mean Licensor and any individual or Legal Entity\n",
" on behalf of whom a Contribution has been received by Licensor and\n",
" subsequently incorporated within the Work.\n",
"\n",
" 2. Grant of Copyright License. Subject to the terms and conditions of\n",
" this License, each Contributor hereby grants to You a perpetual,\n",
" worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n",
" copyright license to reproduce, prepare Derivative Works of,\n",
" publicly display, publicly perform, sublicense, and distribute the\n",
" Work and such Derivative Works in Source or Object form.\n",
"\n",
" 3. Grant of Patent License. Subject to the terms and conditions of\n",
" this License, each Contributor hereby grants to You a perpetual,\n",
" worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n",
" (except as stated in this section) patent license to make, have made,\n",
" use, offer to sell, sell, import, and otherwise transfer the Work,\n",
" where such license applies only to those patent claims licensable\n",
" by such Contributor that are necessarily infringed by their\n",
" Contribution(s) alone or by combination of their Contribution(s)\n",
" with the Work to which such Contribution(s) was submitted. If You\n",
" institute patent litigation against any entity (including a\n",
" cross-claim or counterclaim in a lawsuit) alleging that the Work\n",
" or a Contribution incorporated within the Work constitutes direct\n",
" or contributory patent infringement, then any patent licenses\n",
" granted to You under this License for that Work shall terminate\n",
" as of the date such litigation is filed.\n",
"\n",
" 4. Redistribution. You may reproduce and distribute copies of the\n",
" Work or Derivative Works thereof in any medium, with or without\n",
" modifications, and in Source or Object form, provided that You\n",
" meet the following conditions:\n",
"\n",
" (a) You must give any other recipients of the Work or\n",
" Derivative Works a copy of this License; and\n",
"\n",
" (b) You must cause any modified files to carry prominent notices\n",
" stating that You changed the files; and\n",
"\n",
" (c) You must retain, in the Source form of any Derivative Works\n",
" that You distribute, all copyright, patent, trademark, and\n",
" attribution notices from the Source form of the Work,\n",
" excluding those notices that do not pertain to any part of\n",
" the Derivative Works; and\n",
"\n",
" (d) If the Work includes a \"NOTICE\" text file as part of its\n",
" distribution, then any Derivative Works that You distribute must\n",
" include a readable copy of the attribution notices contained\n",
" within such NOTICE file, excluding those notices that do not\n",
" pertain to any part of the Derivative Works, in at least one\n",
" of the following places: within a NOTICE text file distributed\n",
" as part of the Derivative Works; within the Source form or\n",
" documentation, if provided along with the Derivative Works; or,\n",
" within a display generated by the Derivative Works, if and\n",
" wherever such third-party notices normally appear. The contents\n",
" of the NOTICE file are for informational purposes only and\n",
" do not modify the License. You may add Your own attribution\n",
" notices within Derivative Works that You distribute, alongside\n",
" or as an addendum to the NOTICE text from the Work, provided\n",
" that such additional attribution notices cannot be construed\n",
" as modifying the License.\n",
"\n",
" You may add Your own copyright statement to Your modifications and\n",
" may provide additional or different license terms and conditions\n",
" for use, reproduction, or distribution of Your modifications, or\n",
" for any such Derivative Works as a whole, provided Your use,\n",
" reproduction, and distribution of the Work otherwise complies with\n",
" the conditions stated in this License.\n",
"\n",
" 5. Submission of Contributions. Unless You explicitly state otherwise,\n",
" any Contribution intentionally submitted for inclusion in the Work\n",
" by You to the Licensor shall be under the terms and conditions of\n",
" this License, without any additional terms or conditions.\n",
" Notwithstanding the above, nothing herein shall supersede or modify\n",
" the terms of any separate license agreement you may have executed\n",
" with Licensor regarding such Contributions.\n",
"\n",
" 6. Trademarks. This License does not grant permission to use the trade\n",
" names, trademarks, service marks, or product names of the Licensor,\n",
" except as required for reasonable and customary use in describing the\n",
" origin of the Work and reproducing the content of the NOTICE file.\n",
"\n",
" 7. Disclaimer of Warranty. Unless required by applicable law or\n",
" agreed to in writing, Licensor provides the Work (and each\n",
" Contributor provides its Contributions) on an \"AS IS\" BASIS,\n",
" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n",
" implied, including, without limitation, any warranties or conditions\n",
" of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n",
" PARTICULAR PURPOSE. You are solely responsible for determining the\n",
" appropriateness of using or redistributing the Work and assume any\n",
" risks associated with Your exercise of permissions under this License.\n",
"\n",
" 8. Limitation of Liability. In no event and under no legal theory,\n",
" whether in tort (including negligence), contract, or otherwise,\n",
" unless required by applicable law (such as deliberate and grossly\n",
" negligent acts) or agreed to in writing, shall any Contributor be\n",
" liable to You for damages, including any direct, indirect, special,\n",
" incidental, or consequential damages of any character arising as a\n",
" result of this License or out of the use or inability to use the\n",
" Work (including but not limited to damages for loss of goodwill,\n",
" work stoppage, computer failure or malfunction, or any and all\n",
" other commercial damages or losses), even if such Contributor\n",
" has been advised of the possibility of such damages.\n",
"\n",
" 9. Accepting Warranty or Additional Liability. While redistributing\n",
" the Work or Derivative Works thereof, You may choose to offer,\n",
" and charge a fee for, acceptance of support, warranty, indemnity,\n",
" or other liability obligations and/or rights consistent with this\n",
" License. However, in accepting such obligations, You may act only\n",
" on Your own behalf and on Your sole responsibility, not on behalf\n",
" of any other Contributor, and only if You agree to indemnify,\n",
" defend, and hold each Contributor harmless for any liability\n",
" incurred by, or claims asserted against, such Contributor by reason\n",
" of your accepting any such warranty or additional liability.\n",
"\n",
" END OF TERMS AND CONDITIONS\n",
"\n",
" APPENDIX: How to apply the Apache License to your work.\n",
"\n",
" To apply the Apache License to your work, attach the following\n",
" boilerplate notice, with the fields enclosed by brackets \"[]\"\n",
" replaced with your own identifying information. (Don't include\n",
" the brackets!) The text should be enclosed in the appropriate\n",
" comment syntax for the file format. We also recommend that a\n",
" file or class name and description of purpose be included on the\n",
" same \"printed page\" as the copyright notice for easier\n",
" identification within third-party archives.\n",
"\n",
" Copyright 2023 Esben Jannik Bjerrum\n",
"\n",
" Licensed under the Apache License, Version 2.0 (the \"License\");\n",
" you may not use this file except in compliance with the License.\n",
" You may obtain a copy of the License at\n",
"\n",
" http://www.apache.org/licenses/LICENSE-2.0\n",
"\n",
" Unless required by applicable law or agreed to in writing, software\n",
" distributed under the License is distributed on an \"AS IS\" BASIS,\n",
" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
" See the License for the specific language governing permissions and\n",
" limitations under the License.\n"
]
}
],
"metadata": {
"jupytext": {
"formats": "docs//notebooks//ipynb,docs//notebooks//scripts//py:percent"
},
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
================================================
FILE: docs/notebooks/10_pipeline_pandas_output.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"id": "454d87b5",
"metadata": {},
"source": [
"# Preserving feature information in DataFrames\n",
"\n",
"This notebook highlights the ability of scikit-mol transformers to return data in DataFrames with meaningful column names. Some use-cases of this feature are illustrated.\n",
"\n",
"***NOTE***: The goal of this notebook is to highlight the advantages of storing transformer output in DataFrames with meaningful column names. This notebook should *not* be considered a set of good practices for training and evaluating QSAR pipelines. The performance metrics of the resulting pipelines are pretty bad: the dataset they have been trained on is pretty small. Tuning the hyperparameters of the Random Forest regressor model (maximum depth of the trees, maximum features to consider when splitting...) can be beneficial. Also including dimensionality reduction / feature selection techniques can be beneficial, since pipelines use a high number of features for a small number of samples. Of course, to further reduce the risk of overfitting, the best hyperparameters and preprocessing techniques should be chosen in cross validation."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "cb457069",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:31.171627Z",
"iopub.status.busy": "2024-11-24T09:28:31.171255Z",
"iopub.status.idle": "2024-11-24T09:28:32.152283Z",
"shell.execute_reply": "2024-11-24T09:28:32.151641Z"
}
},
"outputs": [],
"source": [
"from pathlib import Path\n",
"import pandas as pd\n",
"from sklearn.pipeline import make_pipeline\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn.preprocessing import StandardScaler\n",
"from sklearn.ensemble import RandomForestRegressor\n",
"from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score\n",
"from sklearn.preprocessing import FunctionTransformer\n",
"from scikit_mol.conversions import SmilesToMolTransformer\n",
"from sklearn.compose import make_column_selector, make_column_transformer\n",
"from scikit_mol.standardizer import Standardizer\n",
"from scikit_mol.descriptors import MolecularDescriptorTransformer\n",
"from scikit_mol.fingerprints import MorganFingerprintTransformer"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "bc72ca09",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:32.155106Z",
"iopub.status.busy": "2024-11-24T09:28:32.154793Z",
"iopub.status.idle": "2024-11-24T09:28:32.161683Z",
"shell.execute_reply": "2024-11-24T09:28:32.161035Z"
}
},
"outputs": [],
"source": [
"csv_file = Path(\"../../tests/data/SLC6A4_active_excapedb_subset.csv\")\n",
"assert csv_file.is_file()\n",
"data = pd.read_csv(csv_file)\n",
"data.drop_duplicates(subset=\"Ambit_InchiKey\", inplace=True)"
]
},
{
"cell_type": "markdown",
"id": "f482cac3",
"metadata": {},
"source": [
"Let's split the dataset in training and test, so we will be able to use the test set to evaluate the performance of models trained on the training set."
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "6019d09f",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:32.164164Z",
"iopub.status.busy": "2024-11-24T09:28:32.163946Z",
"iopub.status.idle": "2024-11-24T09:28:32.168382Z",
"shell.execute_reply": "2024-11-24T09:28:32.167874Z"
}
},
"outputs": [],
"source": [
"data_train, data_test = train_test_split(data, test_size=0.2, random_state=42)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "fe9efa0e",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:32.171037Z",
"iopub.status.busy": "2024-11-24T09:28:32.170722Z",
"iopub.status.idle": "2024-11-24T09:28:32.174941Z",
"shell.execute_reply": "2024-11-24T09:28:32.174393Z"
}
},
"outputs": [],
"source": [
"column_smiles = \"SMILES\"\n",
"column_target = \"pXC50\"\n",
"\n",
"smis_train = data_train.loc[:, column_smiles]\n",
"target_train = data_train.loc[:, column_target]\n",
"smis_test = data_test.loc[:, column_smiles]\n",
"target_test = data_test.loc[:, column_target]"
]
},
{
"cell_type": "markdown",
"id": "7b4cca39",
"metadata": {},
"source": [
"## Descriptors pipeline that returns DataFrames\n",
"\n",
"Define a pipeline that:\n",
"\n",
"- converts SMILES strings to Mol objects\n",
"- standardizes the molecules\n",
"- computes molecular descriptors\n",
"\n",
"Then, we will configure the pipeline to return output in Pandas DataFrames.\n",
"The column names will correspond to the descriptor names."
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "33ce774b",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:32.177459Z",
"iopub.status.busy": "2024-11-24T09:28:32.177241Z",
"iopub.status.idle": "2024-11-24T09:28:32.194656Z",
"shell.execute_reply": "2024-11-24T09:28:32.194079Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
"
],
"text/plain": [
"Pipeline(steps=[('smilestomoltransformer', SmilesToMolTransformer()),\n",
" ('standardizer', Standardizer()),\n",
" ('moleculardescriptortransformer',\n",
" MolecularDescriptorTransformer(desc_list=['MaxAbsEStateIndex',\n",
" 'MaxEStateIndex',\n",
" 'MinAbsEStateIndex',\n",
" 'MinEStateIndex',\n",
" 'qed', 'SPS',\n",
" 'MolWt',\n",
" 'HeavyAtomMolWt',\n",
" 'ExactMolWt',\n",
" 'NumValenceElectrons',\n",
" 'NumRadicalElectrons',\n",
" 'MaxPa...\n",
" 'MaxAbsPartialCharge',\n",
" 'MinAbsPartialCharge',\n",
" 'FpDensityMorgan1',\n",
" 'FpDensityMorgan2',\n",
" 'FpDensityMorgan3',\n",
" 'BCUT2D_MWHI',\n",
" 'BCUT2D_MWLOW',\n",
" 'BCUT2D_CHGHI',\n",
" 'BCUT2D_CHGLO',\n",
" 'BCUT2D_LOGPHI',\n",
" 'BCUT2D_LOGPLOW',\n",
" 'BCUT2D_MRHI',\n",
" 'BCUT2D_MRLOW',\n",
" 'AvgIpc', 'BalabanJ',\n",
" 'BertzCT', 'Chi0', ...])),\n",
" ('standardscaler', StandardScaler()),\n",
" ('randomforestregressor', RandomForestRegressor(max_depth=5))])"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"params_random_forest = {\n",
" \"max_depth\": 5, # Setting a low maximum depth to avoid overfitting\n",
"}\n",
"\n",
"regression_pipeline = make_pipeline(\n",
" SmilesToMolTransformer(),\n",
" Standardizer(),\n",
" MolecularDescriptorTransformer(),\n",
" StandardScaler(), # Scale the descriptors\n",
" RandomForestRegressor(**params_random_forest),\n",
")\n",
"regression_pipeline.set_output(transform=\"pandas\")"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "f0b2f44f",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:34.643396Z",
"iopub.status.busy": "2024-11-24T09:28:34.643148Z",
"iopub.status.idle": "2024-11-24T09:28:37.656343Z",
"shell.execute_reply": "2024-11-24T09:28:37.655703Z"
},
"lines_to_next_cell": 2
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'DataFrame.swapaxes' is deprecated and will be removed in a future version. Please use 'DataFrame.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'Series.swapaxes' is deprecated and will be removed in a future version. Please use 'Series.transpose' instead.\n",
" return bound(*args, **kwds)\n",
"/home/anton/projects/scikit-mol/.venv/lib/python3.12/site-packages/numpy/_core/fromnumeric.py:57: FutureWarning: 'DataFrame.swapaxes' is deprecated and will be removed in a future version. Please use 'DataFrame.transpose' instead.\n",
" return bound(*args, **kwds)\n"
]
}
],
"source": [
"regression_pipeline.fit(smis_train, target_train)\n",
"pred_test = regression_pipeline.predict(smis_test)"
]
},
{
"cell_type": "markdown",
"id": "3aa6802d",
"metadata": {
"lines_to_next_cell": 2
},
"source": [
"Let's define a simple function to compute regression metrics, and use it to evaluate the test set performance of the pipeline."
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "8b59851a",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:37.658965Z",
"iopub.status.busy": "2024-11-24T09:28:37.658741Z",
"iopub.status.idle": "2024-11-24T09:28:37.666594Z",
"shell.execute_reply": "2024-11-24T09:28:37.665979Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"{'RMSE': 0.8539077762549014,\n",
" 'MAE': 0.7222501985900492,\n",
" 'R2': 0.16145333000722317}"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def compute_metrics(y_true, y_pred):\n",
" result = {\n",
" \"RMSE\": mean_squared_error(y_true=y_true, y_pred=y_pred) ** 0.5,\n",
" \"MAE\": mean_absolute_error(y_true=y_true, y_pred=y_pred),\n",
" \"R2\": r2_score(y_true=y_true, y_pred=y_pred),\n",
" }\n",
" return result\n",
"\n",
"\n",
"performance = compute_metrics(y_true=target_test, y_pred=pred_test)\n",
"performance"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "68528957",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:37.668899Z",
"iopub.status.busy": "2024-11-24T09:28:37.668697Z",
"iopub.status.idle": "2024-11-24T09:28:37.673651Z",
"shell.execute_reply": "2024-11-24T09:28:37.672957Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"
RandomForestRegressor(max_depth=5)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
RandomForestRegressor(max_depth=5)
"
],
"text/plain": [
"RandomForestRegressor(max_depth=5)"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"regressor = regression_pipeline[-1]\n",
"regressor"
]
},
{
"cell_type": "markdown",
"id": "d8f32688",
"metadata": {},
"source": [
"Since we used `set_output(transform=\"pandas\")` on the pipeline, the last step of the pipeline (the regression model) has the descriptor names in the `feature_names_in_` attribute. We can use them and the `feature_importances_` attribute to easily analyze the feature importances."
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "24011e90",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:37.677173Z",
"iopub.status.busy": "2024-11-24T09:28:37.676324Z",
"iopub.status.idle": "2024-11-24T09:28:37.690728Z",
"shell.execute_reply": "2024-11-24T09:28:37.690184Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"
"
],
"text/plain": [
" feature importance\n",
"0 PEOE_VSA6 0.138689\n",
"1 VSA_EState5 0.062832\n",
"2 MaxAbsPartialCharge 0.052241\n",
"3 VSA_EState6 0.048135\n",
"4 SlogP_VSA6 0.027086\n",
".. ... ...\n",
"212 fr_term_acetylene 0.000000\n",
"213 fr_thiazole 0.000000\n",
"214 fr_thiocyan 0.000000\n",
"215 fr_unbrch_alkane 0.000000\n",
"216 fr_urea 0.000000\n",
"\n",
"[217 rows x 2 columns]"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_importance.sort_values(\n",
" by=\"importance\", ascending=False, inplace=True, ignore_index=True\n",
")\n",
"df_importance"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "4b97778f",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:37.703238Z",
"iopub.status.busy": "2024-11-24T09:28:37.703004Z",
"iopub.status.idle": "2024-11-24T09:28:37.707129Z",
"shell.execute_reply": "2024-11-24T09:28:37.706557Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The 5 most important features are:\n",
"PEOE_VSA6\n",
"VSA_EState5\n",
"MaxAbsPartialCharge\n",
"VSA_EState6\n",
"SlogP_VSA6\n"
]
}
],
"source": [
"n_top_features = 5\n",
"top_features = df_importance.head(n_top_features).loc[:, \"feature\"].tolist()\n",
"print(f\"The {n_top_features} most important features are:\")\n",
"for feature in top_features:\n",
" print(feature)"
]
},
{
"cell_type": "markdown",
"id": "f79c93a0",
"metadata": {},
"source": [
"## Including external features\n",
"\n",
"The ability to keep the results of scikit-learn transformers in DataFrames with meaningful column names simplifies the task of analyzing the resulting models.\n",
"\n",
"Another good use-case is when we want to combine cheminformatics features from some other tool (QM packages, Deep Learning embeddings...) with the traditional cheminformatics features available in scikit-mol. It will be easier to keep track of the features that come from scikit-mol and the features that come from other tools, if they are stored in DataFrames with meaningful column names.\n",
"\n",
"Let's include features from the popular [CDDD](https://github.com/jrwnter/cddd) tool. CDDD is a Variational AutoEncoder Deep Learning model, and the CDDD features are the inner latent space representations of the SMILES. For additional details, have a look at the original CDDD paper:\n",
"\n",
"> R. Winter, F. Montanari, F. Noé, and D.-A. Clevert, “Learning continuous and data-driven molecular descriptors by translating equivalent chemical representations,” Chem. Sci., vol. 10, no. 6, pp. 1692–1701, Feb. 2019, [doi: 10.1039/C8SC04175J](https://doi.org/10.1039/C8SC04175J).\n",
"\n",
"We have precomputed these features and stored them in a file:"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "bf8ddaf9",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:37.709630Z",
"iopub.status.busy": "2024-11-24T09:28:37.709389Z",
"iopub.status.idle": "2024-11-24T09:28:37.755699Z",
"shell.execute_reply": "2024-11-24T09:28:37.755108Z"
},
"lines_to_next_cell": 2
},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
Ambit_InchiKey
\n",
"
cddd_1
\n",
"
cddd_2
\n",
"
cddd_3
\n",
"
cddd_4
\n",
"
cddd_5
\n",
"
cddd_6
\n",
"
cddd_7
\n",
"
cddd_8
\n",
"
cddd_9
\n",
"
...
\n",
"
cddd_503
\n",
"
cddd_504
\n",
"
cddd_505
\n",
"
cddd_506
\n",
"
cddd_507
\n",
"
cddd_508
\n",
"
cddd_509
\n",
"
cddd_510
\n",
"
cddd_511
\n",
"
cddd_512
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
RBCQCVSMIQCOMN-PCQZLOAONA-N
\n",
"
0.034484
\n",
"
0.288955
\n",
"
-0.038534
\n",
"
0.485996
\n",
"
0.398606
\n",
"
-0.077340
\n",
"
0.417946
\n",
"
-0.114399
\n",
"
0.340925
\n",
"
...
\n",
"
-0.442085
\n",
"
-0.122121
\n",
"
-0.755012
\n",
"
0.580011
\n",
"
-0.999539
\n",
"
-0.466382
\n",
"
0.378511
\n",
"
0.579342
\n",
"
0.753847
\n",
"
0.812943
\n",
"
\n",
"
\n",
"
1
\n",
"
ALZTYVXVRZIERJ-UHFFFAOYNA-N
\n",
"
-0.784729
\n",
"
0.146379
\n",
"
0.442466
\n",
"
0.187816
\n",
"
0.042911
\n",
"
-0.007460
\n",
"
0.012899
\n",
"
0.170997
\n",
"
-0.322217
\n",
"
...
\n",
"
-0.434862
\n",
"
0.216556
\n",
"
-0.687221
\n",
"
-0.103207
\n",
"
-0.999198
\n",
"
-0.335400
\n",
"
0.136468
\n",
"
0.550440
\n",
"
-0.019943
\n",
"
-0.173729
\n",
"
\n",
"
\n",
"
2
\n",
"
MOEMPBAHOJKXBG-MRXNPFEDNA-N
\n",
"
-0.751528
\n",
"
-0.506115
\n",
"
0.412968
\n",
"
0.341948
\n",
"
0.822811
\n",
"
-0.713795
\n",
"
0.159594
\n",
"
-0.453231
\n",
"
0.053278
\n",
"
...
\n",
"
0.530237
\n",
"
-0.131153
\n",
"
-0.007292
\n",
"
-0.065849
\n",
"
-0.978371
\n",
"
-0.653190
\n",
"
0.404358
\n",
"
-0.079914
\n",
"
0.711537
\n",
"
0.445195
\n",
"
\n",
"
\n",
"
3
\n",
"
HEKGBDCRHYILPL-QWOVJGMINA-N
\n",
"
-0.757406
\n",
"
0.000328
\n",
"
0.670389
\n",
"
0.856043
\n",
"
0.002886
\n",
"
0.064478
\n",
"
0.181017
\n",
"
-0.229966
\n",
"
0.598979
\n",
"
...
\n",
"
0.670772
\n",
"
-0.372262
\n",
"
-0.571060
\n",
"
-0.443543
\n",
"
-0.986363
\n",
"
0.118407
\n",
"
-0.077974
\n",
"
-0.097596
\n",
"
0.283461
\n",
"
-0.099510
\n",
"
\n",
"
\n",
"
4
\n",
"
SNNRWIBSGBMYRF-UKRRQHHQNA-N
\n",
"
-0.477663
\n",
"
-0.129261
\n",
"
-0.332024
\n",
"
-0.591108
\n",
"
0.786510
\n",
"
-0.007520
\n",
"
-0.171381
\n",
"
-0.048844
\n",
"
0.565125
\n",
"
...
\n",
"
0.342538
\n",
"
0.680307
\n",
"
0.662410
\n",
"
-0.493203
\n",
"
-0.987440
\n",
"
-0.731436
\n",
"
0.016999
\n",
"
-0.503085
\n",
"
-0.066302
\n",
"
-0.377198
\n",
"
\n",
"
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
\n",
"
\n",
"
189
\n",
"
PIKWEFAACQLYMF-UHFFFAOYNA-N
\n",
"
-0.354424
\n",
"
0.037133
\n",
"
0.261493
\n",
"
0.191034
\n",
"
0.203483
\n",
"
-0.718652
\n",
"
0.481088
\n",
"
-0.077800
\n",
"
-0.359651
\n",
"
...
\n",
"
0.465482
\n",
"
0.181667
\n",
"
0.008707
\n",
"
0.374962
\n",
"
-0.998080
\n",
"
-0.015004
\n",
"
-0.071801
\n",
"
-0.205790
\n",
"
-0.394928
\n",
"
0.386006
\n",
"
\n",
"
\n",
"
190
\n",
"
AUZWJAMWJZUPHQ-UHFFFAOYNA-N
\n",
"
-0.647606
\n",
"
-0.604185
\n",
"
-0.070398
\n",
"
0.109305
\n",
"
0.667468
\n",
"
-0.239701
\n",
"
-0.332139
\n",
"
-0.490862
\n",
"
0.302364
\n",
"
...
\n",
"
0.268934
\n",
"
0.103272
\n",
"
-0.120228
\n",
"
-0.133202
\n",
"
-0.981479
\n",
"
-0.683975
\n",
"
0.748666
\n",
"
-0.171097
\n",
"
0.053143
\n",
"
0.144776
\n",
"
\n",
"
\n",
"
191
\n",
"
JCEWQICHOLLRDL-WUFINQPMNA-N
\n",
"
-0.681951
\n",
"
-0.346629
\n",
"
0.387501
\n",
"
-0.760321
\n",
"
0.003585
\n",
"
0.173832
\n",
"
0.584196
\n",
"
0.314204
\n",
"
-0.375850
\n",
"
...
\n",
"
-0.401828
\n",
"
0.187382
\n",
"
0.632996
\n",
"
0.507790
\n",
"
-0.999535
\n",
"
0.041612
\n",
"
0.090283
\n",
"
-0.432323
\n",
"
-0.191279
\n",
"
0.136006
\n",
"
\n",
"
\n",
"
192
\n",
"
NGRIUVQYFBDXMT-JYAVWHMHNA-N
\n",
"
-0.622850
\n",
"
-0.760069
\n",
"
-0.175192
\n",
"
0.306767
\n",
"
0.828635
\n",
"
-0.251226
\n",
"
0.095201
\n",
"
0.029581
\n",
"
-0.098511
\n",
"
...
\n",
"
-0.428120
\n",
"
0.510929
\n",
"
-0.112762
\n",
"
0.072157
\n",
"
-0.974629
\n",
"
-0.724549
\n",
"
0.754821
\n",
"
0.580699
\n",
"
0.437276
\n",
"
0.079424
\n",
"
\n",
"
\n",
"
193
\n",
"
ZWLWOTHDIGRTNE-UHFFFAOYNA-N
\n",
"
-0.740121
\n",
"
-0.462145
\n",
"
0.351089
\n",
"
0.104331
\n",
"
0.579055
\n",
"
-0.524488
\n",
"
-0.763961
\n",
"
-0.339895
\n",
"
0.693571
\n",
"
...
\n",
"
-0.461685
\n",
"
-0.582436
\n",
"
0.441268
\n",
"
0.113779
\n",
"
-0.919631
\n",
"
-0.569133
\n",
"
0.647876
\n",
"
-0.348418
\n",
"
0.395181
\n",
"
0.272382
\n",
"
\n",
" \n",
"
\n",
"
194 rows × 513 columns
\n",
"
"
],
"text/plain": [
" Ambit_InchiKey cddd_1 cddd_2 cddd_3 cddd_4 \\\n",
"0 RBCQCVSMIQCOMN-PCQZLOAONA-N 0.034484 0.288955 -0.038534 0.485996 \n",
"1 ALZTYVXVRZIERJ-UHFFFAOYNA-N -0.784729 0.146379 0.442466 0.187816 \n",
"2 MOEMPBAHOJKXBG-MRXNPFEDNA-N -0.751528 -0.506115 0.412968 0.341948 \n",
"3 HEKGBDCRHYILPL-QWOVJGMINA-N -0.757406 0.000328 0.670389 0.856043 \n",
"4 SNNRWIBSGBMYRF-UKRRQHHQNA-N -0.477663 -0.129261 -0.332024 -0.591108 \n",
".. ... ... ... ... ... \n",
"189 PIKWEFAACQLYMF-UHFFFAOYNA-N -0.354424 0.037133 0.261493 0.191034 \n",
"190 AUZWJAMWJZUPHQ-UHFFFAOYNA-N -0.647606 -0.604185 -0.070398 0.109305 \n",
"191 JCEWQICHOLLRDL-WUFINQPMNA-N -0.681951 -0.346629 0.387501 -0.760321 \n",
"192 NGRIUVQYFBDXMT-JYAVWHMHNA-N -0.622850 -0.760069 -0.175192 0.306767 \n",
"193 ZWLWOTHDIGRTNE-UHFFFAOYNA-N -0.740121 -0.462145 0.351089 0.104331 \n",
"\n",
" cddd_5 cddd_6 cddd_7 cddd_8 cddd_9 ... cddd_503 \\\n",
"0 0.398606 -0.077340 0.417946 -0.114399 0.340925 ... -0.442085 \n",
"1 0.042911 -0.007460 0.012899 0.170997 -0.322217 ... -0.434862 \n",
"2 0.822811 -0.713795 0.159594 -0.453231 0.053278 ... 0.530237 \n",
"3 0.002886 0.064478 0.181017 -0.229966 0.598979 ... 0.670772 \n",
"4 0.786510 -0.007520 -0.171381 -0.048844 0.565125 ... 0.342538 \n",
".. ... ... ... ... ... ... ... \n",
"189 0.203483 -0.718652 0.481088 -0.077800 -0.359651 ... 0.465482 \n",
"190 0.667468 -0.239701 -0.332139 -0.490862 0.302364 ... 0.268934 \n",
"191 0.003585 0.173832 0.584196 0.314204 -0.375850 ... -0.401828 \n",
"192 0.828635 -0.251226 0.095201 0.029581 -0.098511 ... -0.428120 \n",
"193 0.579055 -0.524488 -0.763961 -0.339895 0.693571 ... -0.461685 \n",
"\n",
" cddd_504 cddd_505 cddd_506 cddd_507 cddd_508 cddd_509 cddd_510 \\\n",
"0 -0.122121 -0.755012 0.580011 -0.999539 -0.466382 0.378511 0.579342 \n",
"1 0.216556 -0.687221 -0.103207 -0.999198 -0.335400 0.136468 0.550440 \n",
"2 -0.131153 -0.007292 -0.065849 -0.978371 -0.653190 0.404358 -0.079914 \n",
"3 -0.372262 -0.571060 -0.443543 -0.986363 0.118407 -0.077974 -0.097596 \n",
"4 0.680307 0.662410 -0.493203 -0.987440 -0.731436 0.016999 -0.503085 \n",
".. ... ... ... ... ... ... ... \n",
"189 0.181667 0.008707 0.374962 -0.998080 -0.015004 -0.071801 -0.205790 \n",
"190 0.103272 -0.120228 -0.133202 -0.981479 -0.683975 0.748666 -0.171097 \n",
"191 0.187382 0.632996 0.507790 -0.999535 0.041612 0.090283 -0.432323 \n",
"192 0.510929 -0.112762 0.072157 -0.974629 -0.724549 0.754821 0.580699 \n",
"193 -0.582436 0.441268 0.113779 -0.919631 -0.569133 0.647876 -0.348418 \n",
"\n",
" cddd_511 cddd_512 \n",
"0 0.753847 0.812943 \n",
"1 -0.019943 -0.173729 \n",
"2 0.711537 0.445195 \n",
"3 0.283461 -0.099510 \n",
"4 -0.066302 -0.377198 \n",
".. ... ... \n",
"189 -0.394928 0.386006 \n",
"190 0.053143 0.144776 \n",
"191 -0.191279 0.136006 \n",
"192 0.437276 0.079424 \n",
"193 0.395181 0.272382 \n",
"\n",
"[194 rows x 513 columns]"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"file_cddd_features = Path(\"../../tests/data/CDDD_SLC6A4_active_excapedb_subset.csv.gz\")\n",
"assert file_cddd_features.is_file()\n",
"df_cddd = pd.read_csv(file_cddd_features)\n",
"df_cddd"
]
},
{
"cell_type": "markdown",
"id": "92dc6bf5",
"metadata": {
"lines_to_next_cell": 2
},
"source": [
"The CDDD features are stored in columns `cddd_1`, `cddd_2`, ..., `cddd_512`. The file has the identifier column `Ambit_InchiKey` that we can use to combine the CDDD features with the rest of the data:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "db83be01",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:37.758200Z",
"iopub.status.busy": "2024-11-24T09:28:37.757994Z",
"iopub.status.idle": "2024-11-24T09:28:37.769048Z",
"shell.execute_reply": "2024-11-24T09:28:37.768408Z"
}
},
"outputs": [],
"source": [
"def combine_datasets(data, cddd):\n",
" data_combined = pd.merge(\n",
" left=data,\n",
" right=cddd,\n",
" on=\"Ambit_InchiKey\",\n",
" how=\"inner\",\n",
" validate=\"one_to_one\",\n",
" )\n",
" return data_combined\n",
"\n",
"\n",
"data_combined_train = combine_datasets(data_train, df_cddd)\n",
"data_combined_test = combine_datasets(data_test, df_cddd)"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "dae995b7",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:37.771772Z",
"iopub.status.busy": "2024-11-24T09:28:37.771516Z",
"iopub.status.idle": "2024-11-24T09:28:37.775128Z",
"shell.execute_reply": "2024-11-24T09:28:37.774567Z"
}
},
"outputs": [],
"source": [
"# The CDDD descriptors couldn't be computed for few molecules and can be removed as commented out below. The Datafile is now prefiltered\n",
"# target_train = data_train.loc[data_train[\"Ambit_InchiKey\"].isin(data_combined_train[\"Ambit_InchiKey\"]), column_target]\n",
"# target_test = data_test.loc[data_test[\"Ambit_InchiKey\"].isin(data_combined_test[\"Ambit_InchiKey\"]), column_target]\n",
"\n",
"target_train = data_combined_train.loc[:, column_target]\n",
"target_test = data_combined_test.loc[:, column_target]"
]
},
{
"cell_type": "markdown",
"id": "2ec82fc8",
"metadata": {},
"source": [
"Now we can define a pipeline that uses the original SMILES column to compute the descriptors available in scikit-mol, then concatenates them with the pre-computed CDDD features, and uses all of them to train the regression model. We will need a slightly more complex pipeline with column selectors and transformers. For more details on this technique, please refer to the [official documentation](https://scikit-learn.org/stable/modules/generated/sklearn.compose.make_column_selector.html).\n",
"\n",
"Since we will keep everything in DataFrames, it will be easier to understand the effect of the CDDD features and the traditional descriptors available in scikit-mol."
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "dc6de049",
"metadata": {
"execution": {
"iopub.execute_input": "2024-11-24T09:28:37.777567Z",
"iopub.status.busy": "2024-11-24T09:28:37.777354Z",
"iopub.status.idle": "2024-11-24T09:28:37.808615Z",
"shell.execute_reply": "2024-11-24T09:28:37.808024Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.