You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从非均匀分布数据集抽取匹配目标分布的样本?

从非均匀分布数据集抽取匹配目标分布的样本问题

我们需要从数据集ds2中抽取样本,使样本的「mass」变量分布与数据集ds1的「mass」分布完全一致。当ds2的「mass」为均匀分布时,使用ds1的KDE作为权重(通过Pandas的ds2.sample(...,weights=ds1_kde))进行采样,能成功匹配目标分布;但当ds2的「mass」呈非均匀分布时,采样得到的样本会保留ds2的偏斜特性,无法匹配ds1的分布。


成功场景:ds2为均匀分布

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy import stats

# 数据集1(目标分布)
ds1 = pd.DataFrame({'mass':[0,1,1,2,2,2,2,3,3,3,4,4,5,6,7,7,8,8,8,8,9,9,9,9,9,9,9,10,10,10,10,10,10,11,11,11,12,13,14,15]})

# 计算ds1的KDE
ds1_kde = stats.gaussian_kde(ds1.mass.to_list())
ds1_kde.set_bandwidth(bw_method=0.2)

# 均匀分布的数据集2
ds2 = pd.DataFrame({'mass':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]})
ds2['ds1_kde'] = ds2.mass.apply(lambda x: ds1_kde(x)[0])
# 按ds1的KDE权重采样
smpl = ds2.sample(200, weights='ds1_kde', replace=True)

# 计算样本的KDE
smpl_kde = stats.gaussian_kde(smpl.mass.to_list())
smpl_kde.set_bandwidth(bw_method=0.2)

# 绘图对比分布
bins = np.linspace(0, 16, 15)
fig = plt.figure()
xs = np.linspace(0,15,100)
sns.histplot(ds2.mass.to_list(), stat='density', bins=bins, color='blue', label='ds2', alpha=0.5)
sns.histplot(ds1.mass.to_list(), stat='density', bins=bins, color='orange', label='ds1(目标分布)', alpha=0.5)
sns.histplot(smpl.mass.to_list(), stat='density', bins=bins, color='green', label='从ds2抽取的样本', alpha=0.5)
sns.lineplot(x=xs, y=ds1_kde(xs), color='orange', label='ds1_kde')
sns.lineplot(x=xs, y=smpl_kde(xs), color='green', label='样本_kde')
plt.xlabel("mass")
plt.title("ds2为均匀分布时采样成功")
plt.legend()
plt.show()

结果说明:
从ds2抽取的样本「mass」分布与ds1的目标分布高度吻合,样本KDE曲线与ds1的KDE曲线几乎重合。


失败场景:ds2为非均匀分布

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy import stats

# 数据集1(目标分布)
ds1 = pd.DataFrame({'mass':[0,1,1,2,2,2,2,3,3,3,4,4,5,6,7,7,8,8,8,8,9,9,9,9,9,9,9,10,10,10,10,10,10,11,11,11,12,13,14,15]})

# 计算ds1的KDE
ds1_kde = stats.gaussian_kde(ds1.mass.to_list())
ds1_kde.set_bandwidth(bw_method=0.2)

# 非均匀分布的数据集2(mass偏向左端)
ds2 = pd.DataFrame({'mass':[0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,4,4,5,6,7,8,9,10,11,12,13,14,15]})

# 添加ds1的KDE作为采样权重
ds2['ds1_kde'] = ds2.mass.apply(lambda x: ds1_kde(x)[0])
smpl = ds2.sample(200, weights='ds1_kde', replace=True)

# 计算样本的KDE
smpl_kde = stats.gaussian_kde(smpl.mass.to_list())
smpl_kde.set_bandwidth(bw_method=0.2)

# 绘图对比分布
bins = np.linspace(0, 16, 15)
fig = plt.figure()
xs = np.linspace(0,15,100)
sns.histplot(ds2.mass.to_list(), stat='density', bins=bins, color='blue', label='ds2', alpha=0.5)
sns.histplot(ds1.mass.to_list(), stat='density', bins=bins, color='orange', label='ds1(目标分布)', alpha=0.5)
sns.histplot(smpl.mass.to_list(), stat='density', bins=bins, color='green', label='从ds2抽取的样本', alpha=0.5)
sns.lineplot(x=xs, y=ds1_kde(xs), color='orange', label='ds1_kde')
sns.lineplot(x=xs, y=smpl_kde(xs), color='green', label='样本_kde')
plt.xlabel("mass")
plt.title("ds2为偏斜分布时采样失败")
plt.legend()
plt.show()

结果说明:
样本的「mass」分布保留了ds2的左偏特性,无法匹配ds1的目标分布,样本KDE曲线与ds1的KDE曲线存在明显偏差。


问题本质

这是从总体中抽取子样本时,控制变量分布以匹配目标子总体分布场景的简化版本。

内容的提问来源于Stack Exchange,提问作者Kacper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 23:35:20