Google BigQuery · DuckDB · PySynthea synthetic cohort
Columnar DW · serverless SQL · Python-native patient generation · offline analytics
uv add tietai-synthea duckdbamms302 (region asia-southeast1)-- BigQuery SQL — เหมือนที่เรียนมาทั้งหมด SELECT gender, COUNT(*) AS n, AVG(hba1c) AS avg_a1c FROM `your-project.amms302.synthetic_cohort` GROUP BY gender ORDER BY gender;
“SQLite for analytics” — columnar vectorized engine · query CSV/Parquet in-place ไม่ต้อง import
# uv add duckdb
import duckdb
con = duckdb.connect() # in-memory
con.execute("""
SELECT gender, COUNT(*) n,
ROUND(AVG(hba1c),2) avg_a1c
FROM read_csv_auto('synthetic_cohort.csv')
GROUP BY gender""").df()
.df() → pandas DataFrame ทันที
| ประเด็น | BigQuery | DuckDB |
|---|---|---|
| Scale | PB | GB–TB (single node) |
| Setup | account+project | uv add จบ! |
| Cost | pay/query | ฟรี local |
| Offline lab | ✗ | ✓ เราใช้ตัวนี้ |
uv add tietai-synthea → import name = synthea — Python-native, ไม่ต้อง Java/JVM
from synthea import Generator,
GeneratorOptions
opts = GeneratorOptions()
opts.population_size = 50
opts.seed = 42 # reproducible!
gen = Generator(opts)
gen.run()
print(gen.stats)
# {'total_generated': 50, ...}
CLI: uv run synthea -p 50 --state California
-- CASE + GROUP BY บนไฟล์ตรง ๆ
SELECT
CASE WHEN age<40 THEN '18-39'
WHEN age<60 THEN '40-59'
ELSE '60+' END AS band,
COUNT(*) n,
SUM(dm_dx::INT) dm_n
FROM read_csv_auto('synthetic_cohort.csv')
GROUP BY band ORDER BY band;
syntax เดียวกับ wk6–7 — แค่ FROM เปลี่ยนเป็น reader
SELECT age/10*10 AS decade,
COUNT(*) n,
ROUND(AVG(sbp),0) avg_sbp,
ROUND(100.0*SUM(CASE
WHEN hba1c>7 THEN 1 ELSE 0 END)
/COUNT(*),1) pct_uncontrolled
FROM read_csv_auto('synthetic_cohort.csv')
GROUP BY decade ORDER BY decade;
+ matplotlib bar chart ใน ipynb §4
ดร.วิชิต สมบัติ — wichit.s@ubu.ac.th