Reusable autonomous data generator for the DODS toolkit
Project description
dods-datagen
Config-driven synthetic data generator for the DODS toolkit.
Generate CSV datasets from a YAML template:
- categorical + numeric features
- derived features (expressions referencing earlier columns)
- optional noise, clipping, missing values, outliers
Install
pip install dods-datagen
Quick start
import dods.datagen as dg
# 1) Create a starter template (basic)
dg.create_template() # -> template.yaml
# 2) Generate a dataset from that template
df = dg.run("template") # reads template.yaml, writes CSV as configured inside YAML
Use the long template (with more explanations/examples):
import dods.datagen as dg
dg.create_template("template_long") # -> template_long.yaml
df = dg.run("template_long") # reads template_long.yaml
Run from any path:
import dods.datagen as dg
df = dg.run("path/to/my_config") # reads path/to/my_config.yaml
df = dg.run("path/to/my_config.yaml")
Long-Template to read
# =====================================================================
# 🧩 DODS Data Generator — template.yaml (single "features:" list)
# ---------------------------------------------------------------------
# This template shows the recommended structure for your generator:
# 1) Meta (scenario/seed/n/output)
# 2) Features (categorical + numeric + derived) — evaluated top to bottom
# 3) Optional: noise, clip, postprocess (missing/outliers)
#
# Key rule:
# - If you want multi-line formulas, use YAML "|" (literal block) AND wrap
# the expression in parentheses "( ... )".
#
# Why?
# - Your parser will wrap expressions into a Python lambda:
# lambda income, score: <EXPR>
# - A lambda body must be a single expression.
# - Parentheses make multi-line math still "one expression".
# =====================================================================
# ------------------------------------------------------------
# 0) META
# ------------------------------------------------------------
scenario: synthetic
seed: 42
n: 50000
output_path: "data"
filename: "template_long.csv"
# ------------------------------------------------------------
# 1) FEATURES (evaluated in order)
# ------------------------------------------------------------
features:
# -------------------------
# 1.1 CATEGORICAL — sampled from a list
# -------------------------
- city:
type: categorical
values: ["Berlin", "London", "Rome"] # 3 categories
p: [0.40, 0.30, 0.30] # optional (default uniform)
- plan:
type: categorical
values: ["free", "basic", "pro", "enterprise"] # 4 categories (different from city)
p: [0.55, 0.25, 0.15, 0.05]
# -------------------------
# 1.2 NUMERIC — primitives (all shortcuts + sequences)
# Notes:
# - Shortcuts are expanded automatically:
# randint(...) -> np.random.randint(...)
# normal(...) -> np.random.normal(...)
# uniform(...) -> np.random.uniform(...)
# choice(...) -> np.random.choice(...)
#
# - Sequence helpers:
# range(a,b) / arange(a,b) -> np.arange(a,b)
# seq(a,b) -> np.linspace(a,b,n)
# linspace(a,b) -> np.linspace(a,b,n) (if only 2 args given)
#
# - Format:
# Only lambda expressions need quotation marks!
# -------------------------
- age: randint(18, 70, n) # integers in [18, 70)
- rate: uniform(1.0, 5.0, n) # floats in [1, 5)
- var: normal(0, 1, n) # gaussian noise (mean=0, std=1)
- dev: choice([0.6, 0.9, 1.2], n) # pick from a fixed set
- extra: "lambda n: np.random.exponential(2.0, n)" # custom lambda (needs quotes)
# Sequence examples (useful for trends/seasonality/time)
- idx: range(0, n) # 0..n-1 (np.arange)
- wave: np.sin(age) # uses existing column (robust with your engine)
# -------------------------
# 1.3 NUMERIC — mixing (start simple → then richer)
#
# Tip:
# - Comparisons like (city=='Rome') become True/False → behave like 1/0 in math.
# - Keep "income" deterministic here; add randomness later via "noise:".
# -------------------------
# 1) Simple: purely numeric dependency
- score: age * rate
# 2) Slightly richer: numeric + one categorical factor (still one-liner)
- inc: 2000 + 50*age + (city=='Rome')*400
# 3) Richer: numeric + multiple categorical factors (still one-liner)
- inc_adj: |
(inc
+ (plan=='pro')*250
+ (plan=='enterprise')*800)
# -------------------------
# 1.4 CATEGORICAL — derived from numeric
# -------------------------
- segment:
type: categorical
func: np.where(age >= 45, 'senior', 'junior')
# -------------------------
# 1.5 CATEGORICAL — derived from categorical (mapping)
# -------------------------
- region:
type: categorical
func: |
np.where(city=='Berlin','DE',
np.where(city=='London','UK','IT'))
# -------------------------
# 1.6 NUMERIC — derived formula (multi-line, complex mixing)
#
# IMPORTANT:
# - Use "|" to keep line breaks (readability)
# - Wrap expression in parentheses "( ... )" so it stays ONE expression
# when your parser converts it into a lambda.
# -------------------------
- spend: |
(inc_adj * 0.6
+ rate * 12
+ (plan=='pro')*250
+ (plan=='enterprise')*600
- score * 0.15
+ wave * 25)
# Another derived numeric (one-liner)
- widx: (inc_adj + score) / (spend + 1)
# ------------------------------------------------------------
# 2) NOISE (optional)
# Applied AFTER the column is computed.
# Some Integer features may be converted to Float here.
#
# Accepted formats per column:
# - scalar value → stddev
# - [mean, stddev] → tuple
# - lambda / expression → custom generator
# ------------------------------------------------------------
noise:
inc_adj: 150 # stddev = 150 (applied to the whole column)
age: [0, 1.5] # mean=0, stddev=1.5
score: "lambda n: np.random.normal(0, 3, n)" # custom generator (must return array-like of length n)
# ------------------------------------------------------------
# 3) CLIP (optional)
# Enforce min/max bounds per feature: [min, max]
# ------------------------------------------------------------
clip:
age: [18, 70]
inc: [0, 20000]
inc_adj: [0, 25000]
score: [0, 500000]
spend: [0, 50000]
widx: [0, 1000000]
# ------------------------------------------------------------
# 4) POSTPROCESS (optional)
# Missing values:
# - default_ratio: fallback ratio for all columns not listed below
# - columns: per-column missing ratio (0.0–1.0)
#
# Outliers:
# - default_ratio: fallback ratio for all columns not listed below
# - columns: { ratio, magnitude } per column
# magnitude > 1 → values become larger (scaled up)
# magnitude < 1 → values become smaller (scaled down)
# ------------------------------------------------------------
postprocess:
missing:
default_ratio: 0.0
columns:
inc_adj: 0.02 # 2% missing
city: 0.01 # 1% missing
plan: 0.01 # 1% missing
outliers:
default_ratio: 0.0
columns:
inc_adj: { ratio: 0.01, magnitude: 2.5 } # 1% extreme high values
age: { ratio: 0.02, magnitude: 0.7 } # 2% unusually low ages (scaled down)
spend: { ratio: 0.01, magnitude: 1.8 } # 1% high spending spikes
# =====================================================================
# END
# =====================================================================
Notes
- Features are evaluated in order → define dependencies first.
- Multi-line expressions must be a single expression:
use
|and wrap with( ... ). - The CSV output location is defined inside the YAML via:
output_pathfilename
Links
- Homepage: https://github.com/mahaeu/dods-datagen
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
dods_datagen-0.1.1.tar.gz
(27.0 kB
view details)
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 dods_datagen-0.1.1.tar.gz.
File metadata
- Download URL: dods_datagen-0.1.1.tar.gz
- Upload date:
- Size: 27.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c2224467a38b50fad1e439b11bd7d1e191d4bf32cbcb2f3813738b3a162c28fb
|
|
| MD5 |
00b7e4459856da5f8c9394bf2256d2f5
|
|
| BLAKE2b-256 |
6fa5b99dc467ebebc2808714b0976f0ce688efd35d76f24a9120a75a1d322532
|
File details
Details for the file dods_datagen-0.1.1-py3-none-any.whl.
File metadata
- Download URL: dods_datagen-0.1.1-py3-none-any.whl
- Upload date:
- Size: 33.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c8d99f011b4b8656b3d7e248cfbc8a267089c3b05a4d502eb342434bbcd38b4
|
|
| MD5 |
69166d247acc27b5506bb53d20a19f82
|
|
| BLAKE2b-256 |
72abca81f7645ef6912a34b9f5569ab3b27db22f4d425ee3232b82a20b62f1f3
|