feat(stats): describe 落地,修掉一个静默填 NaN 的 bug(L0 8/12)
src/stats/descriptive.py 由用户本人实现,这里做审查 + 代修。
describe:
- 真 bug:df_num.describe().T 把表转反(行=变量、列=指标),而 docstring 与
test_describe_reports_expected_keys 定的是"行=指标、列=变量"。转置后
.loc[指标名] = <按变量索引的 Series> 与列名零交集,pandas 不报错,直接把
missing / missing_ratio / skewness / kurtosis 四行整行填成 NaN(静默丢数据);
weights 分支则报 cannot set a row with mismatched columns。去掉 .T 一处修好三件事
- 补 median 行(pandas 只有 50%,测试契约定的是 median)
- 入参放宽到 list / tuple / ndarray(00_quickstart.py 传的就是 ndarray)
- weights 校验补齐:维度 / 长度 / NaN / 负值 / 和为 0(原先和为 0 时裸抛 ZeroDivisionError)
- docstring 按 4.7 补 Parameters / Returns / Raises
zscore: 修 RET505;docstring 补齐;DataFrame 取列处按坑 8 用 cast 收窄
coefficient_of_variation: 均值为 0 改抛 ValueError(取值问题不是类型问题);
空数组提前报错(原先静默 nan + RuntimeWarning);错别字与文案修正
tests: 去掉 test_stats.py 的模块级 pytestmark —— 它把 6 条测试全部跳过(含已实现的
describe),正是决策 26 要禁的写法。改为逐条 skip 未实现的 5 条,并新增 20 条用例。
验证:pytest 102 passed / 39 skipped(原 82/40);ruff All checks passed;pyright 0 errors。
examples/01_clean_and_describe.py 填掉 TODO(L0),实测 exit 0。
docs: STATUS.md L0 8/12 + 决策 35/36 + 三处待拍板口径;CHANGELOG 记录;
personal-pitfalls 追加第 11 条(pandas 对不齐就静默填 NaN)
This commit is contained in:
1 parent
4552aee41c
commit
e9624cb3a7
6 files changed
+468
-34
No files matched your search
@@ -159,3 +159,21 @@
|
||||
才在**最小范围**加 `# type: ignore[具体错误码]`;裸 `# type: ignore` 会连带关掉后面所有行
|
||||
(更好的写法见 `docs/04-environment.md` 坑 8 的 `cast`)。
|
||||
- 首次:2026-10-02|复发:0
|
||||
|
||||
### 11. pandas 对不齐就静默填 NaN,不报错
|
||||
|
||||
- 现象:`describe` 里为了"行 = 变量、列 = 指标"多做了一次 `.T`,然后
|
||||
`table.loc["missing"] = df_num.isna().sum()`。跑起来**一声不响**,表里却多出四行
|
||||
**全 NaN**(`missing` / `missing_ratio` / `skewness` / `kurtosis`)。
|
||||
`.loc[新行标签] = Series` 是按**列名**对齐的:Series 的索引是变量名、表的列名是
|
||||
指标名,两边**没有一个交集**,pandas 于是把整行填成 NaN —— 不抛异常。
|
||||
同一个 `.T` 让 `weights` 分支换成 ndarray 后反而直接报
|
||||
`ValueError: cannot set a row with mismatched columns` —— 那个报错才是救命的。
|
||||
- 为什么会错:脑子里想的是"给这一行赋值",pandas 做的是"按标签对齐再赋值"。
|
||||
对齐失败在 pandas 里是**合法结果**(就是缺失),不是错误 —— 它不会替你判断
|
||||
"这次对齐失败是不是手滑"。
|
||||
- 以后怎么防:① 往表里加一行前,先确认 Series 的索引 == 目标轴的标签(列名),
|
||||
拿不准就 `print(list(series.index))` 对着 `list(table.columns)` 看一眼;
|
||||
② 新加的行/列**立刻断言不是全 NaN**,别只看"代码跑过去了";
|
||||
③ 记住这次的信号差异:长度不对(ndarray)会报错,Series **不会** —— 后者更危险。
|
||||
- 首次:2026-10-03|复发:0
|
||||
Reference in new issue
Block a user