Operations research on tidy dataframes — a backend-agnostic dataframe façade over Google OR-Tools.
Project description
ortidy
OR (operations research) on tidy dataframes — a backend-agnostic dataframe façade over Google OR-Tools.
ortidyis the revival ofpandas-or, rebuilt around Narwhals so it works natively with pandas, Polars, and more — pandas in, pandas out; Polars in, Polars out.pandas-orusers: see Migrating.
The thesis: bridge operations research and the data ecosystem so solver outputs come back as tidy dataframes ready for analysis, plotting, and dashboards.
Installation
pip install ortidy
ortidy brings its own OR-Tools. Bring your own dataframe backend (pandas,
polars, …) — install whichever you already use.
Quickstart
Every solver accepts a native frame, returns the same backend, and hands back
a SolveResult carrying the result frame, a status, the objective, and
solve metadata.
import pandas as pd
import ortidy
items = pd.DataFrame({"value": [60, 100, 120], "weight": [10, 20, 30]})
result = ortidy.knapsack(items, capacity=50)
print(result.status) # SolveStatus.OPTIMAL
print(result.objective) # 220
print(result.frame) # items + an `isIncluded` boolean column
Every solver is a plain function — pass a native frame (pandas, Polars, …) and
get a SolveResult back in the same backend.
Result contract
Three result shapes cover every solver:
| Shape | Solvers | Result |
|---|---|---|
| selection | knapsack, multi_knapsack, bin_packing |
rows mapped to bins/resources |
| edge-flow | solve_routing (more in progress) |
values on an edge list |
| interval-schedule | scheduling (roadmap) | intervals on a timeline |
Every solver returns a SolveResult:
result.frame # native dataframe, same backend as the input
result.status # OPTIMAL / FEASIBLE / INFEASIBLE / UNBOUNDED / MODEL_INVALID
result.objective # objective value (None when no solution)
result.metadata # solver name, wall time, bounds, …
bool(result) # True when OPTIMAL or FEASIBLE — a FEASIBLE solution is a success
Solvers
| Shape | Function | Problem |
|---|---|---|
| selection | knapsack |
0/1 & multidimensional knapsack |
| selection | multi_knapsack |
multiple knapsack |
| selection | bin_packing |
bin packing (minimize bins) |
| selection | assignment |
linear assignment |
| selection | generalized_assignment |
GAP (capacity-limited agents) |
| selection | facility_location |
uncapacitated facility location |
| selection | set_cover |
set cover / partition |
| edge-flow | max_flow / min_cost_flow / shortest_path |
network flow |
| edge-flow | transportation |
transportation problem |
| edge-flow | solve_routing (+ distance_matrix) |
vehicle routing (TSP/VRP/CVRP/VRPTW/pickups) |
| interval-schedule | shift_scheduling |
employee rostering |
| interval-schedule | job_shop |
job-shop scheduling |
See the docs for a worked example of each.
Sample datasets ship with the package:
from ortidy import data
items = data.items_knapsack() # pandas by default
items = data.items_knapsack("polars") # or Polars
Examples
Runnable notebooks live in examples/ — knapsack/bin-packing, a
haversine world-tour TSP, and capacitated vehicle routing, each plotted with
Plotly. Try them in your browser with no install:
Migrating from pandas-or
ortidy is pandas-or renamed and rebuilt. Install ortidy and import ortidy
(the old pandas-or 0.1.3 on PyPI is unmaintained). The key changes:
- Solvers return a
SolveResultobject, not a bare frame /None. - Rows are identified by explicit id columns, never a positional index.
- The backend is whatever you pass in (pandas, Polars, …), not just pandas.
License
Apache-2.0.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ortidy-0.4.0.tar.gz.
File metadata
- Download URL: ortidy-0.4.0.tar.gz
- Upload date:
- Size: 235.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f713b032d14fac133e0d6f158057fe31c398fef729374297c797addc25fe9c1
|
|
| MD5 |
2e88e2efe7959e17ffdec88e94bfdd83
|
|
| BLAKE2b-256 |
2ead0c300e9cab07edec8273ac880be6d44c9f8d45d81bc1415d4664834f3293
|
File details
Details for the file ortidy-0.4.0-py3-none-any.whl.
File metadata
- Download URL: ortidy-0.4.0-py3-none-any.whl
- Upload date:
- Size: 42.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c6c66d6da0bd466c48e02bf8af936f1bcbf0f224eb2cf97dfca93db92fde415
|
|
| MD5 |
c908508976171a3887f83f1748354544
|
|
| BLAKE2b-256 |
f8335ede177c6661b334b38560f6f4265d72be6f061ff1ccee62d58a5de07b20
|