如何计算Python中两个分布的重叠及边缘非重叠区域面积
计算两个分布非重叠区域面积的实现方案
核心逻辑:归一化后的KDE曲线积分均为1,两个分布的非重叠区域总面积等于所有采样点上两个KDE概率密度值的绝对差的积分结果。
你可以直接基于原始数据用scipy.stats.gaussian_kde拟合核密度估计后计算,完整代码如下:
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt from scipy.stats import gaussian_kde from scipy.integrate import trapz # 你的原始示例数据 data1 = np.random.normal(0, 0.1, 100) data2 = np.random.normal(0, 0.3, 100) x0 = pd.Series(data1) x1 = pd.Series(data2) # 1. 拟合两个数据集的KDE kde0 = gaussian_kde(x0) kde1 = gaussian_kde(x1) # 2. 生成覆盖两个分布全部范围的统一x采样网格 x_min = min(x0.min(), x1.min()) - 0.5 x_max = max(x0.max(), x1.max()) + 0.5 x_grid = np.linspace(x_min, x_max, 10000) # 采样点越多计算精度越高 # 3. 计算两个KDE在采样网格上的概率密度值 kde0_vals = kde0(x_grid) kde1_vals = kde1(x_grid) # 4. 计算非重叠区域面积 = 两个密度绝对差的积分 non_overlap_area = trapz(np.abs(kde0_vals - kde1_vals), x_grid) print(f"两个分布非重叠区域总面积为: {non_overlap_area:.4f}") # 可视化验证和你的示例效果一致 kwargs = dict(hist_kws={'alpha':.01}, kde_kws={'linewidth':2}) sns.distplot(x0, bins=3, color="dodgerblue", **kwargs) sns.distplot(x1, bins=3, color="orange", **kwargs) # 改了颜色方便区分两个分布 plt.title(f"非重叠面积: {non_overlap_area:.4f}") plt.show()
分布可视化效果参考:
结果说明
- 如果两个分布完全重叠,计算结果接近0
- 如果两个分布完全不重叠,计算结果接近2(因为两个归一化KDE的积分各为1,总和为2)
- 你也可以根据需求单独计算单侧边缘的非重叠面积:比如只计算小于两个分布左交点区间的积分,或者大于右交点区间的积分,只要调整x_grid的取值范围即可。
内容的提问来源于stack exchange,提问作者Seji
相关产品推荐
相关产品推荐

