afrikana-analytics
Production-ready analytics toolkit for any operator managing customers, infrastructure, and growth decisions at scale
Built from real analytical work across African markets. Applicable to any subscription, usage-based, or network-deployment business — mobility, fintech, telecoms, utilities, logistics, or SaaS.
Covers the full data-to-decision stack: churn prediction, customer lifetime value, financial modelling, site deployment optimisation, and demand forecasting.
Installation
# From GitHub Packages
pip install afrikana-analytics
# From source
git clone https://github.com/Peterson-Muriuki/afrikana-analytics
cd afrikana-analytics
pip install -e .
Quick Start
from afrikana.churn import ChurnScorer
from afrikana.ltv import LTVCalculator
from afrikana.financial import FinancialModel
from afrikana.stations import StationOptimizer
from afrikana.forecast import DemandForecaster
# --- Churn prediction ---
scorer = ChurnScorer()
scorer.fit(customers_df)
at_risk = scorer.at_risk(customers_df, threshold=0.5)
print(f"At-risk customers: {len(at_risk)}")
print(scorer.feature_importances())
# --- Customer LTV ---
calc = LTVCalculator(gross_margin=0.62)
result = calc.compute(customers_df)
print(calc.tier_summary(result))
print(calc.revenue_at_risk(result))
# --- Station financial model ---
model = FinancialModel(swap_price_usd=2.50, n_stations=20)
print(model.unit_economics())
print(model.breakeven())
print(model.dcf())
print(model.scenarios())
mc = model.monte_carlo(n_sims=2000)
print(f"NPV P50: ${mc['npv_p50']:,.0f} Prob +ve NPV: {mc['prob_positive_npv']}%")
# --- Deployment optimisation ---
opt = StationOptimizer()
candidates = opt.generate_grid((-1.286389, 36.817223), n=40)
scored = opt.score(candidates, existing_stations_df)
print(opt.recommend(scored, top_n=5))
# --- Demand forecasting ---
fc = DemandForecaster()
daily = fc.prepare_daily(swap_events_df)
forecast = fc.predict(daily, periods=30)
print(fc.forecast_summary(forecast))
Modules
ChurnScorer
Gradient Boosting churn predictor for subscription/usage-based mobility businesses.
from afrikana.churn import ChurnScorer, ChurnScorerConfig
config = ChurnScorerConfig(n_estimators=200, verbose=True)
scorer = ChurnScorer(config)
scorer.fit(df) # trains and evaluates on held-out split
scored = scorer.score(df) # adds churn_score [0-1] and churn_risk tier
at_risk = scorer.at_risk(df, 0.6) # customers above threshold, sorted
scorer.feature_importances() # what drives churn most
print(scorer.summary()) # {"auc": 0.82, "top_feature": "last_swap_days_ago", ...}
Required columns: swap_freq_monthly, last_swap_days_ago, tenure_months, monthly_revenue, churned (0/1 target)
LTVCalculator
Discounted survival-adjusted Customer Lifetime Value with Bronze/Silver/Gold tiers.
from afrikana.ltv import LTVCalculator
calc = LTVCalculator(gross_margin=0.62, discount_rate_annual=0.12, max_horizon_months=36)
df = calc.compute(customers_df) # adds ltv, ltv_tier, expected_lifetime
calc.tier_summary(df) # count, avg_ltv, total_ltv per tier
calc.segment_summary(df, "country") # LTV by country / segment / city
calc.revenue_at_risk(df, threshold=0.5)
Required columns: churn_probability (or churn_score), monthly_revenue, tenure_months
FinancialModel
Full financial model for an EV swap station network.
from afrikana.financial import FinancialModel
model = FinancialModel(
swap_price_usd=2.50,
swaps_per_station_day=18,
n_stations=20,
gross_margin_pct=0.62,
discount_rate_annual=0.12,
)
model.unit_economics() # per-station P&L: revenue, EBITDA, NOPAT, contribution/swap
model.pl_projection() # 36-month network P&L as DataFrame
model.cash_flow() # operating CF, capex, FCF, cumulative cash
model.breakeven() # swaps/day needed, margin of safety, payback period
model.dcf() # NPV, IRR, ROI, terminal value
model.scenarios() # Base / Bull / Bear comparison table
model.monte_carlo(2000) # P10/P50/P90 NPV distribution, VaR 95%, prob +ve NPV
StationOptimizer
Multi-criteria deployment scorer for new swap station locations.
from afrikana.stations import StationOptimizer, OptimizerConfig
config = OptimizerConfig(
weight_demand_density=0.30,
weight_coverage_gap=0.25,
weight_revenue_potential=0.25,
weight_underserved=0.20,
)
opt = StationOptimizer(config)
candidates = opt.generate_grid((-1.286, 36.817), n=40) # synthetic grid
scored = opt.score(candidates, existing_stations_df)
top5 = opt.recommend(scored, top_n=5)
stats = opt.coverage_stats(scored)
Required columns in existing_stations_df: lat, lon, status
DemandForecaster
Holt-Winters time-series forecaster with confidence intervals.
from afrikana.forecast import DemandForecaster
fc = DemandForecaster(seasonal_periods=7)
daily = fc.prepare_daily(swap_events_df)
monthly = fc.prepare_monthly(swap_events_df)
forecast = fc.predict(daily, periods=30) # date, forecast, lower, upper
summary = fc.forecast_summary(forecast)
peaks = fc.peak_hours(swap_events_df) # 24-row hour-of-day breakdown
Running the Demo
pip install -e .
python examples/spiro_demo.py
Running Tests
pip install -e ".[dev]"
pytest tests/ -v --cov=afrikana
Target Markets
Built for and tested against data patterns from:
| Country | Cities | Currency |
|---|---|---|
| Kenya | Nairobi, Mombasa, Kisumu, Nakuru | KES |
| Nigeria | Lagos, Abuja, Kano, Port Harcourt | NGN |
| Rwanda | Kigali, Butare, Gisenyi | RWF |
| Uganda | Kampala, Entebbe, Jinja | UGX |
| Ghana | Accra, Kumasi, Tamale | GHS |
| Ethiopia | Addis Ababa, Dire Dawa | ETB |
Author
Peterson Mutegi — Data Analyst · AI Engineer · Financial Engineer
Nairobi, Kenya · pitmuriuki@gmail.com
GitHub · [LinkedIn
Built on top of real analytical work for African EV mobility operations.
License
MIT — see LICENSE for details.
Metadata
Release files for afrikana-analytics 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| afrikana_analytics-0.1.2.tar.gz | 23.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| afrikana_analytics-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.6 kB
Release files / afrikana_analytics-0.1.2.tar.gz
| Download URL | afrikana_analytics-0.1.2.tar.gz |
|---|---|
| Size | 23.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8e71f302ad805c0b0f507889b9001a4a49e39ccff642750d5c94c156da4c3606
|
|
BLAKE2b-256 checksum How to use checksums |
bc1510f70912c74cab5609b8a452e7abd98e3b8e8cfc88e225bae8f1f3c70ca4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.6
|
Release files / afrikana_analytics-0.1.2-py3-none-any.whl
| Download URL | afrikana_analytics-0.1.2-py3-none-any.whl |
|---|---|
| Size | 20.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
79577d080420df8c1e2eea85950aff9277e11c5b7d0d68de96a16d5196e1592f
|
|
BLAKE2b-256 checksum How to use checksums |
240dfa2d9aab5d77930886f548e36a9386ca8060207f1eeb1f254ebce0a04dc4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.6
|
Security for afrikana-analytics 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.