Python bindings for the xtensor C++ multi-dimensional array library.
xtensor-python enables seamless interoperability between NumPy arrays and C++ through the xtensor library. It provides:
- Zero-copy NumPy array integration with C++
- Broadcasting and universal functions compatible with NumPy
- STL-compliant APIs for familiar C++ development
- Header-only library for easy integration
- High performance through lazy evaluation and expression templates
pip install xtensor-python
conda install -c conda-forge xtensor-python
# or
mamba install -c conda-forge xtensor-pythongit clone https://github.com/xtensor-stack/xtensor-python.git cd xtensor-python pip install -e .
The Python package provides utilities for building C++ extensions:
import xtensor_python # Get include directories for your C++ build include_dirs = xtensor_python.get_include() print(include_dirs) # Use in your setup.py or pyproject.toml from pybind11.setup_helpers import build_ext from xtensor_python import get_cmake_dir # CMake integration cmake_dir = get_cmake_dir()
Create a C++ extension using xtensor-python:
#include <pybind11/pybind11.h> #include <xtensor/xmath.hpp> #include <xtensor-python/pyarray.hpp> // Enable numpy import #define FORCE_IMPORT_ARRAY #include <xtensor-python/pyarray.hpp> double sum_of_sines(xt::pyarray<double>& arr) { auto sines = xt::sin(arr); // Lazy evaluation return std::accumulate(sines.begin(), sines.end(), 0.0); } PYBIND11_MODULE(my_extension, m) { xt::import_numpy(); m.def("sum_of_sines", sum_of_sines, "Sum the sines of array elements"); }
cmake_minimum_required(VERSION 3.15) project(my_extension) find_package(Python COMPONENTS Interpreter Development REQUIRED) find_package(pybind11 REQUIRED) find_package(xtensor-python REQUIRED) pybind11_add_module(my_extension src/main.cpp) target_link_libraries(my_extension PRIVATE xtensor-python::xtensor-python)
Dynamic multi-dimensional arrays that can be reshaped:
#include <xtensor-python/pyarray.hpp> void process_dynamic(xt::pyarray<double>& arr) { // Can reshape to different dimensions arr.reshape({10, 5}); // Changes are reflected in Python }
Fixed-dimension arrays with compile-time optimization:
#include <xtensor-python/pytensor.hpp> void process_2d(xt::pytensor<double, 2>& tensor) { // Fixed 2D tensor - faster than pyarray // Shape is stack-allocated auto result = xt::sum(tensor, {1}); // Sum along axis 1 }
find_package(xtensor-python REQUIRED) target_link_libraries(mylib xtensor-python)
-
Install via pip:
pip install xtensor-python
-
Update CMakeLists.txt:
find_package(Python COMPONENTS Interpreter Development REQUIRED) find_package(xtensor-python REQUIRED) target_link_libraries(mylib PRIVATE xtensor-python::xtensor-python)
-
Or use in setup.py:
from pybind11.setup_helpers import build_ext import xtensor_python ext_modules = [ Pybind11Extension( "my_module", ["src/main.cpp"], include_dirs=[xtensor_python.get_include()], ), ]
- Installation: Use
pip install xtensor-pythoninstead of conda/manual builds - CMake: The package now provides proper CMake config files
- Headers: Automatically available through Python package
- Dependencies: Managed through pip/pyproject.toml
Create vectorized functions from scalar C++ functions:
#include <xtensor-python/pyvectorize.hpp> double scalar_func(double x, double y) { return std::sin(x) - std::cos(y); } PYBIND11_MODULE(my_module, m) { xt::import_numpy(); m.def("vectorized_func", xt::pyvectorize(scalar_func)); }
#include <xtensor-python/pynative_casters.hpp> // Automatic casting between NumPy and xtensor types void process_array(const xt::xarray<double>& arr) { // Function automatically accepts NumPy arrays }
# setup.py from pybind11.setup_helpers import Pybind11Extension, build_ext import xtensor_python ext_modules = [ Pybind11Extension( "my_extension", ["src/main.cpp"], include_dirs=[xtensor_python.get_include()], cxx_std=14, ), ] setup( name="my_package", ext_modules=ext_modules, cmdclass={"build_ext": build_ext}, )
[build-system] requires = ["setuptools", "pybind11", "xtensor-python"] [tool.setuptools] packages = ["my_package"] [[tool.setuptools.ext-modules]] name = "my_package._core" sources = ["src/main.cpp"]
- Python: ≥3.8
- NumPy: ≥2.0
- pybind11: ≥2.6.1,<4
- xtensor: ≥0.26.0 (automatically resolved)
- Use pytensor for fixed dimensions - faster than pyarray
- Leverage lazy evaluation - operations are computed only when needed
- Minimize copies - xtensor-python provides zero-copy views
- Use broadcasting - automatic shape alignment like NumPy
Complete examples are available in the documentation:
Full documentation is available at: https://xtensor-python.readthedocs.io/
Contributions are welcome! Please see our contributing guidelines.
This project is licensed under the BSD 3-Clause License - see the LICENSE file for details.
- Documentation: https://xtensor-python.readthedocs.io/
- Issues: https://github.com/xtensor-stack/xtensor-python/issues
- Discussions: https://github.com/xtensor-stack/xtensor-python/discussions
- Gitter: https://gitter.im/QuantStack/Lobby