使用np.exp()处理Pandas DataFrame列时出现NaN,如何实现概率归一化?
解决Softmax数值溢出问题,生成和为1的概率值
问题原因
你遇到的是数值溢出导致的异常结果:np.exp(2012)的结果超出了浮点数的表示范围,会被判定为inf(无穷大),使得分母sum(np.exp(df.val))同样为inf。计算时inf/inf得到NaN,较小数值的np.exp结果除以inf得到0.0,最终出现你看到的异常输出。
解决方案:数值稳定的Softmax实现
Softmax的数学本质可以等价变形,通过先减去当前列的最大值来避免指数爆炸,公式为:
$$\text{softmax}(x_i) = \frac{e^{x_i - \max(x)}}{\sum_{j}e^{x_j - \max(x)}}$$
对应代码实现:
import numpy as np import pandas as pd # 原始DataFrame df = pd.DataFrame({'id': [1, 1, 1], 'val': [10, 2012, 65]}) # 数值稳定的概率转换 max_val = df['val'].max() df['val'] = np.exp(df['val'] - max_val) / np.exp(df['val'] - max_val).sum()
执行结果
运行后得到的结果符合数学逻辑:
id val 0 1 0.000000 1 1 1.000000 2 1 0.000000
由于2012远大于10和65,经过偏移后,它对应的指数值为1,其余两个值的指数值趋近于0,归一化后概率自然趋近于1和0。
扩展:分组计算概率(多id场景)
如果你的数据包含多个id分组,需要对每个id组内的val计算概率,可以使用分组变换:
df['val'] = df.groupby('id')['val'].transform( lambda x: np.exp(x - x.max()) / np.exp(x - x.max()).sum() )
内容的提问来源于stack exchange,提问作者Eisen
相关产品推荐
相关产品推荐

