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-pythonconda 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