fix(stats): CV 改用 |mean|,并记录决策 37/38/39 与经验 12
coefficient_of_variation: - 分母由 mean 改为 |mean|(用户本人改),均值为负时 CV 不再是负值 - docstring 摘要 / Returns / Notes 同步,加一条测试钉住"均值为负时 CV 仍为正" 口径拍板(2026-10-03): - 决策 37: 非数值列的处置按输出契约分,不按包分 —— describe/zscore 丢掉(吐数值结果表), detect_outliers 保留列、掩码恒 False(吐与原表同形的掩码),刻意不统一 - 决策 38: CV 用 sigma/|mean| - 决策 39: 工作约定 —— 语义/非法输入口径由用户拍板,Codex 只列选项不代选; ruff / STATUS.md / CHANGELOG.md / tests / docstring 这类与算法无关的工程事务 Codex 顺手补 经验(docs/dev/personal-pitfalls.md,只追加): - 第 12 条: 三个并列的 if 让后面的静默覆盖前面的(transform.normalize 三种 method 实际只走 max) 第 11 条(上一轮)是 descriptive 的 .loc 对齐失败静默填 NaN —— 两条的共同点是"不抛异常" 验证: pytest 103 passed / 39 skipped;ruff All checks passed;pyright 0 errors。 docs: STATUS.md 决策 37/38/39 + 下一步;CHANGELOG 记录
This commit is contained in:
1 parent
e9624cb3a7
commit
cfc1be31ca
5 files changed
+58
-20
No files matched your search
@@ -173,7 +173,7 @@ def zscore(x: Any, ddof: int = 0) -> Any:
|
||||
|
||||
|
||||
def coefficient_of_variation(x: Any) -> float:
|
||||
"""变异系数 `std / mean` —— 跨量纲比较"谁更波动"时的唯一正确做法。
|
||||
"""变异系数 `std / |mean|` —— 跨量纲比较"谁更波动"时的唯一正确做法。
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@@ -184,7 +184,7 @@ def coefficient_of_variation(x: Any) -> float:
|
||||
Returns
|
||||
-------
|
||||
float
|
||||
`std / mean`,标准差按总体口径(`ddof=0`)。
|
||||
`std / |mean|`,标准差按总体口径(`ddof=0`)。恒非负。
|
||||
|
||||
Raises
|
||||
------
|
||||
@@ -195,9 +195,9 @@ def coefficient_of_variation(x: Any) -> float:
|
||||
|
||||
Notes
|
||||
-----
|
||||
CV 只有在**均值为正**的比率尺度数据上才有意义:均值为负时本函数返回负值,
|
||||
那不是"波动更小",只是符号跟着均值走;均值接近 0 时 CV 会被放大到任意大。
|
||||
这两类数据请换用别的离散度指标。
|
||||
分母取的是 `|mean|`:均值为负时 CV 仍是正数,不会因为符号反过来被误读成"波动更小"。
|
||||
但 CV 的**可比性**仍然只在均值远离 0 的比率尺度数据上成立 —— 均值接近 0 时
|
||||
CV 会被放大到任意大,那种数据请换用别的离散度指标。
|
||||
"""
|
||||
allowed_type = (list, tuple, np.ndarray, pd.Series)
|
||||
if isinstance(x, pd.DataFrame):
|
||||
@@ -220,4 +220,4 @@ def coefficient_of_variation(x: Any) -> float:
|
||||
if mean == 0:
|
||||
raise ValueError("均值为 0,无法计算变异系数(分母为 0)")
|
||||
|
||||
return float(std / mean)
|
||||
return np.abs(float(std / mean))
|
||||
Reference in new issue
Block a user