Busabase
Busabase is an open-source (MIT) database and workspace for AI agents — data, docs, skills, and apps in one place. Run it locally, self-host it inside your network, or use Busabase Cloud, and turn age
翻译准备中
Retail analytics in Python: RFM, HML and threshold segmentation, gain/loss, cross-shop, cohort retention, revenue trees and market basket analysis, on pandas or in your database via Ibis
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Renamed from pyretailscience in v0.45.0 (April 2026). Install openretailscience; imports change from
pyretailscience to openretailscience.
To get the latest release:
pip install openretailscience
Alternatively, if you want the very latest version of the package you can install it from GitHub:
pip install git+https://github.com/Data-Simply/openretailscience.git
Reliable Results: Built with extensive unit testing and best practices, OpenRetailScience ensures the accuracy and reliability of your analyses. Confidently present your findings, knowing they're backed by a robust, well-tested framework.
Professional Charts: Say goodbye to hours of tweaking chart styles. OpenRetailScience delivers beautifully standardized visualizations that are presentation-ready with just a few lines of code. Impress stakeholders and save time with our pre-built, customizable chart templates.
Here is an excerpt from the gain loss analysis example notebook
from openretailscience.analysis.gain_loss import GainLoss
gl = GainLoss(
df,
# Flag the rows of period 1
p1_index=time_period_1,
# Flag the rows of period 2
p2_index=time_period_2,
# Flag which rows are part of the focus group.
# Namely, which rows are Calvin Klein sales
focus_group_index=df["brand_name"] == "Calvin Klein",
focus_group_name="Calvin Klein",
# Flag which rows are part of the comparison group.
# Namely, which rows are Diesel sales
comparison_group_index=df["brand_name"] == "Diesel",
comparison_group_name="Diesel",
# Finally we specifiy that we want to calculate
# the gain/loss in total revenue
value_col="total_price",
)
# Ok now let's plot the result
gl.plot(
x_label="Revenue Change",
source_text="Transactions 2023-01-01 to 2023-12-31",
move_legend_outside=True,
)
plt.show()
Here is an excerpt from the cross shop analysis example notebook
from openretailscience.analysis import cross_shop
cs = cross_shop.CrossShop(
df,
group_1_col="category_name",
group_1_val="Jeans",
group_2_col="category_name",
group_2_val="Shoes",
group_3_col="category_name",
group_3_val="Dresses",
labels=["Jeans", "Shoes", "Dresses"],
)
cs.plot(
title="Jeans are a popular cross-shopping category with dresses",
source_text="Source: Transactions 2023-01-01 to 2023-12-31",
figsize=(6, 6),
)
plt.show()
# Let's see which customers were in which groups
display(cs.cross_shop_df.head())
# And the totals for all groups
display(cs.cross_shop_table_df)
Here is an excerpt from the customer retention analysis example notebook
from openretailscience.plots import histogram
from openretailscience.plots.styles.graph_utils import set_axis_percent
ax = histogram.plot(
df=dbp.df["avg_days_between_purchases"],
figsize=(10, 5),
bins=20,
cumulative=True,
density=True,
source_text="Source: Transactions in 2023",
title="When Do Customers Make Their Next Purchase?",
)
set_axis_percent(ax.yaxis, decimals=0, xmax=1.0)
# Let's dress up the chart a bit of text and get rid of the legend
churn_period = dbp.purchases_percentile(0.8)
ax.axvline(x=churn_period, color="black", linestyle="--", lw=2)
ax.annotate(
f"80% of customers made\nanother purchase within\n{round(churn_period)} days",
xy=(churn_period, 0.81),
xytext=(dbp.df["avg_days_between_purchases"].min(), 0.8),
fontsize=15,
ha="left",
va="center",
arrowprops=dict(facecolor="black", arrowstyle="-|>", connectionstyle="arc3,rad=-0.25", mutation_scale=25),
)
ax.legend().set_visible(False)
plt.show()
Please see this site for full documentation, which includes:
We welcome contributions from the community to enhance and improve OpenRetailScience. To contribute, please follow these steps:
main branch.Please make sure to follow the existing coding style and provide unit tests for new features.
This repository is supported by Data simply.
If you are interested in seeing what Data Simply can do for you, then please email email us. We work with companies at a variety of scales and with varying levels of data and retail analytics sophistication, to help them build, scale or streamline their analysis capabilities.
Made with contrib.rocks.
Built with expertise doing analytics and data science for scale-ups to multi-nationals, including:
OpenRetailScience includes comprehensive unit and integration tests to ensure reliability across different backends.
Run unit tests using pytest:
# Install dependencies
uv sync
# Run all unit tests
uv run pytest
# Run specific test file
uv run pytest tests/test_file.py
# Run with coverage
uv run pytest --cov=openretailscience
OpenRetailScience supports Python 3.11 through 3.14. You can test across all supported versions locally using tox:
# Test all supported Python versions
tox -e py311,py312,py313,py314
# Test specific Python version
tox -e py314
# Run tests in parallel across versions
tox -p auto
Prerequisites:
uv sync installs it automatically)Integration tests verify that all analysis modules work correctly across different backends: distributed computing engines (PySpark, BigQuery, Snowflake, Databricks) and relational databases (SQL Server, Oracle). These tests ensure the Ibis-based code paths function properly across different execution environments.
The PySpark integration tests run locally using the same pytest framework as other tests.
Prerequisites:
uv sync --group integration)Running locally:
# Run all PySpark tests
uv run pytest tests/integration -k "pyspark" -v
# Run specific PySpark test
uv run pytest tests/integration/test_cohort_analysis.py -k "pyspark" -v
The BigQuery integration tests verify compatibility with Google BigQuery as a backend.
Prerequisites:
test_data, table: transactions)Running locally:
# Set up authentication
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/your/service-account-key.json
export GCP_PROJECT_ID=your-project-id
# Install dependencies (the backend drivers live in a non-default group)
uv sync --group integration
# Run all BigQuery tests
uv run pytest tests/integration -k "bigquery" -v
# Run specific test module
uv run pytest tests/integration/bigquery/test_cohort_analysis.py -v
The Snowflake integration tests verify compatibility with Snowflake as a backend.
Prerequisites:
TRANSACTIONS)Running locally:
# Set up Snowflake connection
export SNOWFLAKE_CI_ACCOUNT=your-account-identifier
export SNOWFLAKE_CI_USER=your-username
export SNOWFLAKE_CI_WAREHOUSE=your-warehouse
export SNOWFLAKE_CI_DATABASE=your-database
export SNOWFLAKE_CI_SCHEMA=your-schema
export SNOWFLAKE_CI_PRIVATE_KEY_PATH=/path/to/your/private-key.p8
# Install dependencies (the backend drivers live in a non-default group)
uv sync --group integration
# Run all Snowflake tests
uv run pytest tests/integration -k "snowflake" -v
# Run specific test module
uv run pytest tests/integration/test_cohort_analysis.py -k "snowflake" -v
The Databricks integration tests verify compatibility with Databricks as a backend. They query a pre-loaded Unity Catalog table over a SQL warehouse, authenticating as an OAuth machine-to-machine service principal.
Prerequisites:
USE_CATALOG, USE_SCHEMA and SELECT on the test
schema, plus CREATE VOLUME, READ VOLUME and WRITE VOLUME: Ibis creates a volume on connect to stage
memtables, so a principal holding only SELECT cannot open the connection<catalog>.<schema>.transactions), kept in step with
data/transactions.parquet, which the seeded backends build their copy fromtest_data volume in the same schema, which CI stages the wheel and test module intoRunning locally:
# Set up Databricks connection. HOST/CLIENT_ID/CLIENT_SECRET are the standard
# Databricks SDK variables, so a ~/.databrickscfg profile works instead.
export DATABRICKS_HOST=https://your-workspace.cloud.databricks.com
export DATABRICKS_CLIENT_ID=your-service-principal-client-id
export DATABRICKS_CLIENT_SECRET=your-service-principal-secret
export DATABRICKS_CI_HTTP_PATH=/sql/1.0/warehouses/your-warehouse-id
export DATABRICKS_CI_CATALOG=your-catalog
export DATABRICKS_CI_SCHEMA=your-schema
# Install dependencies (the backend drivers live in a non-default group)
uv sync --group integration
# Run all Databricks tests
uv run pytest tests/integration -k "databricks" -v
# Run specific test module
uv run pytest tests/integration/test_cohort_analysis.py -k "databricks" -v
install_skills copies the bundled agent skills into /Workspace/Users/<current_user()>/.assistant/skills,
a mount that exists only on Databricks compute. Coverage is shared between:
tests/test_skills.py::TestDatabricksInstall runs on every commit, against a temp directory and a
stub Spark session. It covers the states a real workspace will not produce on demand.tests/integration/test_workspace_skills.py holds every assertion made against the real mount.
Plain pytest skips it.skills-install-tests job in .github/workflows/databricks-integration.yml delivers it, running
a wheel built from the working tree rather than the last PyPI release.DATABRICKS_RUNTIME_VERSION guard lives.To run them by hand, attach a Databricks notebook to serverless compute and execute the following. They delete and reinstall the bundled skills in your own workspace home:
%pip install openretailscience pytest
%restart_python
import pytest
pytest.main(["/Workspace/path/to/test_workspace_skills.py", "-v", "-p", "no:cacheprovider"])
SQL Server and Oracle run against throwaway Docker containers, so they execute the same way locally and in CI. CI covers the supported free editions: SQL Server Developer 2022 and 2025, and Oracle 23ai Free.
These backends have a one-time setup (the SQL Server ODBC driver) and per-version image tags, so their instructions live next to the Compose files. See tests/integration/docker/README.md for prerequisites, the version matrix, and the commands to start a container and run the tests.
This project is licensed under the Elastic License 2.0 - see the LICENSE file for details.