Skip to main content

A declarative DSL for DataFrame column calculations

Project description

中文 English

⚗️ Calchemy

数据炼金术 — 为 DataFrame 列运算设计的声明式 DSL
让业务方、LLM 和技术方说同一种语言

Python 3.10+ Tests License


✨ 一行表达式完成列计算

传统 pandas 代码对业务方不可读,也让 LLM 承担不必要的翻译成本。Calchemy 用一行自然语言风格的表达式完成列计算:

业务人员也能看懂的对比

❌ 传统 pandas —— 业务方看不懂的"天书"

df["毛利率"] = (
    df["销售额"] - df["成本"]
) / df["销售额"]
df["毛利率"] = df["毛利率"].apply(
    lambda x: f"{x:.2%}" if pd.notna(x) else x
)

✅ Calchemy —— 业务方直接能读

calc(df, "毛利率 = (销售额 - 成本) / 销售额 >>> %")

业务人员不需要理解 df["毛利率"] = ...apply(lambda x: ...)Calchemy 表达式本身就是业务语言——毛利率 = (销售额 - 成本) / 销售额,一眼就能看懂并核对。

常见业务场景速查

业务需求 Calchemy 表达式
计算毛利 calc(df, "毛利 = 销售额 - 成本")
计算毛利率 calc(df, "毛利率 = (销售额 - 成本) / 销售额 >>> %")
计算增值税(13%) calc(df, "税额 = 销售额 * 0.13")
计算净利润 calc(df, "净利润 = 销售额 - 成本 - 税额")
计算同比增长率 calc(df, "同比增长 = (本年 - 去年) / 去年 >>> %")
计算客单价(GMV / 订单数) calc(df, "客单价 = GMV / 订单数")
计算人均产出 calc(df, "人均产出 = 总产出 / 人数")
计算标准差中的平方项 calc(df, "平方差 = (X - 均值) ** 2")
计算对数收益率 calc(df, "对数收益 = log(收盘价 / 昨收)")
计算 n 次方根 calc(df, "立方根 = root(X, 3)")

💡 字段名支持中文销售额成本)或常见英文简写GMVCOGSDAU),DSL 自动识别。

Calchemy = Calc + Alchemy。把原始数据"炼"成业务指标——这就是数据炼金术。

"Every DataFrame has gold in it. Calchemy helps you extract it."

三方受益

角色 价值
🧑‍💼 业务方 直接读懂计算逻辑,无需看 pandas 代码,可自行核对字段定义
🧑‍💻 技术方 用 DSL 表达式替代重复性 pandas 模板代码,防御性处理内置
🤖 LLM / AI 直接输出 DSL 表达式而非 pandas 代码,减少语法错误与调试往返

🚀 快速上手

安装

pip install calchemy

或直接将 calchemy/ 目录复制到项目中,仅依赖 pandasnumpy

30 秒示例

import pandas as pd
from calchemy import calc

df = pd.DataFrame({
    "销售额": [100, 200, 0, 400],
    "成本":   [60,  150, 0, 300],
})

# 混合运算 + 百分比格式(字段名直接用中文!)
calc(df, "毛利 = 销售额 - 成本")
calc(df, "毛利率 = 毛利 / 销售额 >>> %")

print(df[["销售额", "成本", "毛利", "毛利率"]])

输出:

   销售额  成本  毛利   毛利率
0    100   60   40  40.00%
1    200  150   50  25.00%
2      0    0    0     nan
3    400  300  100  25.00%

📖 DSL 语法

基础格式

新列名 = 列A <运算符> 列B
新列名 = 列A <运算符> 列B >>> 格式

混合运算(支持括号)

gm_rate = (revenue - cogs) / revenue >>> %
tax = revenue * 0.13

操作数:列名(无引号)或数字常量 运算符+ - * / ** ^ 函数abs(列名) log(列名) log(列名, 底数) sqrt(列名) 格式后缀>>> 后):%/pct/percent/百分比 → 百分比;省略 → 浮点数

API 列表

函数 用途 示例
calc() 🌟 混合运算引擎(推荐) calc(df, "rate = (a - b) / c >>> %")
calc_add() 加法 calc_add(df, "total = a + b")
calc_sub() 减法 calc_sub(df, "margin = a - b")
calc_mul() 乘法 calc_mul(df, "gmv = qty * price")
calc_div() 除法(含零值保护) calc_div(df, "rate = a / b >>> %")

💡 简单两操作数运算可用 calc_* helper,混合运算请用 calc()


🛡️ 错误处理(errors 参数)

所有函数均支持 errors 参数,命名对齐 pd.to_datetime(errors=...)

errors 行为 适用场景
'coerce'(默认) NaN 和零分母 → NaN;脏数据 → 0 🏭 生产报表,容错优先
'raise' 遇零分母或 NaN 立刻抛 ValueError 🔍 数据校验,严格模式
'ignore' 跳过问题行,保留原列值 🔄 幂等重跑,不覆盖已有结果
# 严格模式:有问题直接报错
calc(df, "rate = a / b", errors='raise')

# 忽略模式:有问题跳过
calc(df, "rate = a / b", errors='ignore')

NaN 处理语义

情况 结果
任一操作数为 NaN NaN
除法:0 / 0 NaN(无意义)
除法:非零 / 0 0(脏数据强制归零,避免 ∞)
0 × NaN NaN(不做隐式填 0)

🔒 安全性

calc() 使用 ast.parse 受限子集解析表达式:

  • ✅ 允许:列名(Name)、数字常量(Constant)、四则运算(BinOp)、正负号(UnaryOp)、白名单函数(abs/log/sqrt/root
  • ❌ 禁止:任意函数调用、属性访问、下标、比较运算、eval()
# ❌ 以下表达式会被拒绝
calc(df, 'r = __import__("os").system("ls")')  # 函数调用
calc(df, 'r = a.__class__')                     # 属性访问
calc(df, 'r = a > b')                           # 比较运算

📁 项目结构

calchemy/
├── calchemy/               # 包目录
│   ├── __init__.py         # 公共 API 入口
│   ├── types.py            # 数据结构:CalcStep, CalcResult
│   ├── utils.py            # 校验与格式化工具
│   ├── helpers.py          # 运算 helper(四则运算 + 扩展运算)
│   ├── parse.py            # AST 解析与拆解
│   ├── calc.py             # 混合运算引擎
│   └── chain.py            # 链式调用 API
├── tests/                  # 测试目录
│   ├── __init__.py
│   └── test_calchemy.py   # 测试套件(124 用例)
├── README.md               # 中文文档(本文件)
├── README_EN.md            # English documentation
└── .gitignore

🗺️ 开发路线

阶段 内容 状态
Phase 1 除法 calc_div ✅ 完成
Phase 2 加减乘 helper + errors 参数统一 ✅ 完成
Phase 2.5 项目结构重组:标准 Python 包 ✅ 完成
Phase 3 混合运算引擎 calc()(括号 + 常量) ✅ 完成
Phase 3.5 拆解引擎 _calc_decompose():逐步执行 + 血缘追踪 ✅ 完成
Phase 4 链式调用 Calchemy ✅ 完成(111 测试通过)
Phase 4.5 扩展运算符(指数 **/^、对数 log、绝对值 abs、平方根 sqrt、n次方根 root ✅ 完成(124 测试通过)
Phase 5 LLM Function Calling schema + Skill 文档 🔲 规划中
Phase 6 跨后端适配(polars / SQL) 🔲 规划中
Phase 7 指标注册表 + 血缘图谱 🔲 规划中

🎯 设计原则

  1. 零隐式魔法:NaN 处理语义必须通过 errors 参数显式声明
  2. 列名即文档:DSL 表达式本身就是业务逻辑的可读文档
  3. 防御性优先:类型检查先于运算,精确报错优于强制转换
  4. LLM 友好:函数签名和 docstring 以 LLM 直接调用为目标
  5. 跨后端可迁移:同一套 DSL 可在不同后端执行(Phase 6)

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

calchemy-0.1.0.tar.gz (33.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

calchemy-0.1.0-py3-none-any.whl (26.6 kB view details)

Uploaded Python 3

File details

Details for the file calchemy-0.1.0.tar.gz.

File metadata

  • Download URL: calchemy-0.1.0.tar.gz
  • Upload date:
  • Size: 33.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for calchemy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 76e6762ab8571dcc4f372a8da04c3e8da905a825eb93542d92e1f9fe0576ed62
MD5 b1439bc628dc959fa1bd9ec87ffff74d
BLAKE2b-256 4183b6ada85419edd2ddddb2accbc16acfffe78d7a89ec55c6f4573d93a99793

See more details on using hashes here.

Provenance

The following attestation bundles were made for calchemy-0.1.0.tar.gz:

Publisher: publish.yml on CoderMoray/Calchemy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file calchemy-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: calchemy-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 26.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for calchemy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 55a01ef20339c691092848ecd943195a5a69e705213dc3e374eba467b3954645
MD5 81819be9c7d0c9aea4f55cd71560f36b
BLAKE2b-256 4964ec8deb2f83796dfc3fd8a8f84abfab4d267f5b08acca3418048ec107c755

See more details on using hashes here.

Provenance

The following attestation bundles were made for calchemy-0.1.0-py3-none-any.whl:

Publisher: publish.yml on CoderMoray/Calchemy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page