pandas设置DatetimeIndex后pint量化值显示NaN如何解决
问题根因
这个现象不是你的操作错误,是pint-pandas扩展类型在pandas DataFrame初始化阶段的索引对齐兼容bug:你单独构造每一列pint类型Series时,默认使用从0开始的整数索引,当你在构造DataFrame时直接传入DatetimeIndex作为全局索引,pint扩展数组不会触发普通类型的自动重索引逻辑,而是直接按索引匹配取值,整数索引和时间索引没有任何匹配项,最终所有值就显示为NaN。
pint-pandas目前仍处于0.x早期开发阶段,对DatetimeIndex、重采样、多表合并等pandas原生操作的兼容确实存在不少边缘场景问题。
可直接复用的解决方案
两种写法都能同时兼容DatetimeIndex和pint字节单位,且满足你单位仅用于计算换算、视图展示,不固化到原始数据的需求:
- 方案1:先构造带pint单位的DataFrame,最后统一赋值时间索引(写法最简洁)
# 构造阶段不传入index,避免初始化时的索引对齐问题 df = pd.DataFrame( { "code": pd.Series(mem_code, dtype="pint[byte]"), "data": pd.Series(mem_data, dtype="pint[byte]"), "heap": pd.Series(mem_heap, dtype="pint[byte]"), "stack": pd.Series(mem_stack, dtype="pint[byte]"), "total": pd.Series(mem_total, dtype="pint[byte]"), } ) # 构造完成后再赋值DatetimeIndex,不会触发pint类型的对齐bug df.index = pd.DatetimeIndex(dt) print(df.pint.dequantify())
运行后所有数值和单位都会正常显示,不会出现NaN。
- 方案2:构造每一列pint Series时提前指定和全局一致的DatetimeIndex
如果需要在DataFrame初始化阶段就绑定索引,可以给每个Series提前传入相同的DatetimeIndex,保证索引完全匹配,不会出现对齐失配:
dt_index = pd.DatetimeIndex(dt) df = pd.DataFrame( { "code": pd.Series(mem_code, dtype="pint[byte]", index=dt_index), "data": pd.Series(mem_data, dtype="pint[byte]", index=dt_index), "heap": pd.Series(mem_heap, dtype="pint[byte]", index=dt_index), "stack": pd.Series(mem_stack, dtype="pint[byte]", index=dt_index), "total": pd.Series(mem_total, dtype="pint[byte]", index=dt_index), }, index=dt_index )
使用提示
你不需要把单位固化到模型数据中:日常做内存相关计算时直接操作pint列即可,pint会自动完成字节、KB、MB等单位的换算,不需要手动写转换逻辑;需要取纯数值数据时,调用.pint.dequantify()就能拿到带单位标注的纯数值表,或者直接用.astype(int)/.astype(float)剥离单位拿到原始数值即可。
后续使用pint-pandas如果遇到类似的NaN问题,优先排查是不是不同索引在DataFrame初始化阶段触发了对齐bug,先构造列再赋值索引的写法可以绕开绝大多数这类兼容问题。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

