多DataFrame绘制箱线图报错且生成空图,求解决方案
问题描述
我拥有4个DataFrame:
df1 = pd.DataFrame({'ID': [0, 0, 0, 0, 0, 0], 'value': [3.0, 3.5, 4.5, NaN, 7.0, 8.1]}) df2 = pd.DataFrame({'ID': [1, 1, 1, 1, 1, 1], 'value': [9.4, NaN, 4.5, 2.4, 4.0, 3.9]}) df3 = pd.DataFrame({'ID': [2, 2, 2], 'value': [1.0, 3.9, 4.1]}) df4 = pd.DataFrame({'ID': [3, 3, 3, 3], 'value': [NaN, NaN, 5.8, 3.0]})
想要基于每个DataFrame的value列绘制箱线图,编写了如下代码:
fig, ax2 = plt.subplots() vec = [df1['value'].values,df2['value'].values,df3['value'].values,df4['value'].values] labels = ['ID_0','ID_1', 'ID_2', 'ID_3'] ax2.boxplot(vec, labels = labels) ax2.set_title('Values') plt.show()
但代码无法正常运行,生成空图还抛出以下错误:
回溯信息
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Input In [3], in <cell line: 1>() 1 df1 = pd.DataFrame({'ID': [0, 0, 0, 0, 0, 0], ----> 2 'value': [3.0, 3.5, 4.5, NaN, 7.0, 8.1]}) 4 df2 = pd.DataFrame({'ID': [1, 1, 1, 1, 1, 1], 5 'value': [9.4, NaN, 4.5, 2.4, 4.0, 3.9]}) 7 df3 = pd.DataFrame({'ID': [2, 2, 2], 8 'value': [1.0, 3.9, 4.1]}) NameError: name 'NaN' is not defined
求更好的解决方法?
解决方法
1. 修复NaN未定义错误
Python中NaN不是内置常量,必须从numpy导入后使用np.nan,或者用pandas的pd.NA替代。修改DataFrame定义代码:
import numpy as np import pandas as pd df1 = pd.DataFrame({'ID': [0, 0, 0, 0, 0, 0], 'value': [3.0, 3.5, 4.5, np.nan, 7.0, 8.1]}) df2 = pd.DataFrame({'ID': [1, 1, 1, 1, 1, 1], 'value': [9.4, np.nan, 4.5, 2.4, 4.0, 3.9]}) df3 = pd.DataFrame({'ID': [2, 2, 2], 'value': [1.0, 3.9, 4.1]}) df4 = pd.DataFrame({'ID': [3, 3, 3, 3], 'value': [np.nan, np.nan, 5.8, 3.0]})
2. 优化箱线图绘制代码
方法一:保留原DataFrame结构绘制
直接传入Series列表给boxplot即可,无需转成.values(matplotlib会自动忽略NaN值):
import matplotlib.pyplot as plt fig, ax2 = plt.subplots() # 直接传入Series,处理NaN更稳妥 vec = [df1['value'], df2['value'], df3['value'], df4['value']] labels = ['ID_0','ID_1', 'ID_2', 'ID_3'] ax2.boxplot(vec, labels=labels) ax2.set_title('Values') ax2.set_ylabel('Value') plt.show()
方法二:合并DataFrame后用pandas绘制(更简洁)
将多个DataFrame合并为一个,利用ID列分组绘制,代码更易维护:
# 合并所有DataFrame combined_df = pd.concat([df1, df2, df3, df4], ignore_index=True) # pandas内置箱线图自动按ID分组 combined_df.boxplot(column='value', by='ID') plt.title('Values by ID') plt.suptitle('') # 移除pandas自动生成的顶部标题 plt.ylabel('Value') plt.show()
原代码空图原因
原代码因NaN未定义导致DataFrame创建失败,后续绘图代码未执行,因此生成空图。修复NaN问题后,即使转成.values数组,matplotlib也能处理NaN,但直接传入Series是更可靠的方式。
内容的提问来源于stack exchange,提问作者EngGu
相关产品推荐
相关产品推荐

