Seaborn热图中总计行列数值为何从int转为float?
解决Pandas总计行列因NaN变为浮点型的问题
问题描述
给DataFrame添加「Total」列和「Total」行后,原本能正常显示整数总计;但将表格中值为0的单元格替换为np.nan后,总计行列的数值变成带.0的浮点类型,尝试用astype(np.int64)转换无效。
原代码:
df = pd.DataFrame( values, index=index, columns=columns ) df['Total'] = df.sum(axis=1, numeric_only=True) df.loc[f'Total'] = df.sum(numeric_only=True) df[df == 0] = np.nan # 掩码部分与问题无关 mask = np.zeros_like(df, dtype=bool) mask[:, -1] = True mask[0, :] = True sns.heatmap( data=df, vmin=0, vmax=values.max(), annot=True, fmt='g', cmap=colormap, linewidths=0.5, linecolor='black', mask=mask, annot_kws={ 'size': 10, } )
尝试过的无效转换代码:
df['Total'] = df['Total'].astype(np.int64) df.loc[f'Total'] = df.loc[f'Weekly Total'].astype(np.int64)
原因分析
- Pandas的整数类型无法存储
np.nan,当表格中出现NaN时,整列会自动升级为浮点型,导致原本的整数总计也被转为带.0的float。 - 转换代码中存在索引名错误:
df.loc[f'Weekly Total']应为df.loc['Total'],这也是转换无效的直接原因之一。 - 使用
np.int64转换无法兼容NaN,即使转换成功,赋值回DataFrame后会被重新转为浮点型。
解决方案
方案1:调整操作顺序+使用Nullable整数类型
先替换0为NaN,再计算总计,并用Pandas的Int64(大写I)类型存储,该类型可同时兼容整数和NaN:
df = pd.DataFrame(values, index=index, columns=columns) # 先替换0为NaN df[df == 0] = np.nan # 计算Total列并转为Nullable整数类型 df['Total'] = df.sum(axis=1, numeric_only=True).astype('Int64') # 计算Total行并转为Nullable整数类型 df.loc['Total'] = df.sum(numeric_only=True).astype('Int64') # 后续掩码和热图代码不变 mask = np.zeros_like(df, dtype=bool) mask[:, -1] = True mask[0, :] = True sns.heatmap( data=df, vmin=0, vmax=values.max(), annot=True, fmt='g', cmap=colormap, linewidths=0.5, linecolor='black', mask=mask, annot_kws={'size': 10} )
方案2:直接修改热图显示格式
如果不想改动数据类型,可在seaborn.heatmap中强制指定整数格式,忽略浮点型的.0:
sns.heatmap( data=df, vmin=0, vmax=values.max(), annot=True, fmt='.0f', # 强制显示为整数 cmap=colormap, linewidths=0.5, linecolor='black', mask=mask, annot_kws={'size': 10} )
方案3:修正转换代码(适合原操作顺序)
修正索引名错误,改用Nullable整数类型转换:
# 原代码替换NaN后执行 df['Total'] = df['Total'].astype('Int64') # 修正索引名,同时转换类型 df.loc['Total'] = df.sum(numeric_only=True).astype('Int64')
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

