Python中如何跳过NaN与Inf值绘图?含Pandas数据处理场景
解决Pandas计算后Inf/NaN导致的绘图报错问题
这个问题我太熟悉了!当你用Pandas做除法产生Inf(因为除数为0)后,绘图库(比如matplotlib)确实会因为无法识别这些无效值抛出ValueError: Axis limits cannot be NaN or Inf。其实解决思路很简单——把计算后产生的NaN和Inf值过滤掉就行,下面给你几个具体的实现方案:
方案1:计算后直接过滤无效行
先完成m4的计算,然后通过布尔索引和dropna()剔除包含Inf或NaN的行,用干净的数据绘图:
import pandas as pd import matplotlib.pyplot as plt # 先构造你的原始数据(模拟示例) data = { 'm1': [4, 3, 4, 2, 4, 3], 'm2': [5, 2, 3, 5, 3, 4], 'm3': [2, 3, 4, 0, 8, 0] } df = pd.DataFrame(data) # 计算m2/m3得到m4 df['m4'] = df['m2'] / df['m3'] # 过滤掉包含Inf或NaN的行 filtered_df = df[~df['m4'].isin([float('inf'), float('-inf')])].dropna(subset=['m4']) # 绘制m1和m4的关系图 plt.scatter(filtered_df['m1'], filtered_df['m4']) plt.xlabel('m1') plt.ylabel('m2/m3') plt.show()
这里~df['m4'].isin([float('inf'), float('-inf')])用来排除正/负无穷大的行,dropna()则处理可能出现的NaN(比如0/0的情况)。
方案2:先替换无效值再过滤
如果觉得直接写索引太繁琐,可以先把Inf替换成NaN,再统一用dropna()删除:
import numpy as np # 计算m4 df['m4'] = df['m2'] / df['m3'] # 将Inf替换为NaN df['m4'] = df['m4'].replace([float('inf'), float('-inf')], np.nan) # 删除包含NaN的行 filtered_df = df.dropna(subset=['m4']) # 绘图 plt.scatter(filtered_df['m1'], filtered_df['m4']) plt.show()
这种方式更直观,把所有无效值统一转成NaN后再清理,逻辑更清晰。
方案3:绘图时直接过滤(无需新DataFrame)
如果不想创建新的DataFrame,可以在绘图时直接用掩码过滤有效数据,一步到位:
# 计算m4 df['m4'] = df['m2'] / df['m3'] # 生成有效数据的掩码 valid_mask = df['m4'].notna() & ~df['m4'].isin([float('inf'), float('-inf')]) # 只传入有效数据绘图 plt.scatter(df['m1'][valid_mask], df['m4'][valid_mask]) plt.xlabel('m1') plt.ylabel('m2/m3') plt.show()
这种方式更节省内存,适合处理大型数据集。
可选:替换无效值而非删除(谨慎使用)
如果你不想丢失行数据,也可以把Inf替换成一个合理的数值(比如数据中有效m4的最大值),但要注意这会改变数据分布,需根据业务场景判断:
# 找到m4的有效最大值 max_valid_m4 = df['m4'][~df['m4'].isin([float('inf'), float('-inf')])].max() # 将Inf替换为这个最大值 df['m4'] = df['m4'].replace([float('inf'), float('-inf')], max_valid_m4) # 直接绘图 plt.scatter(df['m1'], df['m4']) plt.show()
内容的提问来源于stack exchange,提问作者sci-guy
相关产品推荐
相关产品推荐

