如何结合random_state与numpy生成器,按正态分布对Pandas DataFrame进行抽样?
如何结合random_state与numpy生成器,按正态分布对Pandas DataFrame进行抽样?
嘿,我来帮你搞定这个问题!你现在的代码报错,核心是对sample()方法里的random_state参数理解错啦——它可不是用来指定抽样分布的,咱们先说说问题出在哪,再给你两种靠谱的实现方式:
先说说你代码里的问题
rng.normal()会返回一个正态分布的浮点数,但sample()的random_state参数只接受这三类值:整数、numpy.random.RandomState实例,或者numpy.random.Generator实例。它的作用是控制抽样的随机性,让结果可复现,不是用来定义抽样的分布规则,所以你那样写肯定会报错~
方法一:用权重实现正态分布加权抽样
如果想让抽样概率符合正态分布,最直接的方式是给每个样本分配基于正态分布的权重,然后用sample()的weights参数来做加权抽样。比如我们可以围绕数据的均值生成正态分布权重:
import pandas as pd import numpy as np # 生成示例DataFrame(替换成你的数据就行) temp = np.random.randint(1, 101, size=100) df = pd.DataFrame({'temperature': temp}) # 初始化numpy随机生成器 rng = np.random.default_rng() # 基于temperature列的均值和标准差生成正态分布权重 mean_temp = df['temperature'].mean() std_temp = df['temperature'].std() # 生成每个样本对应的正态分布概率密度作为权重 weights = rng.normal(loc=mean_temp, scale=std_temp, size=len(df)) # 确保权重非负(正态分布可能会生成负数,这里取绝对值修正) weights = np.abs(weights) # 可选:归一化权重(sample方法会自动归一化,这步可以省略) weights = weights / weights.sum() # 按权重抽取10个样本,同时用rng作为random_state保证结果可复现 sampled_df = df.sample(n=10, weights=weights, random_state=rng)
方法二:直接生成正态分布的索引选取行
如果你想直接基于正态分布选择行索引,比如围绕DataFrame的中间位置抽样,可以先生成符合正态分布的索引值,再筛选出有效索引来选取样本:
import pandas as pd import numpy as np # 生成示例DataFrame temp = np.random.randint(1, 101, size=100) df = pd.DataFrame({'temperature': temp}) rng = np.random.default_rng() # 定义正态分布的中心(取DataFrame的中间索引)和标准差(控制抽样范围) mid_idx = len(df) // 2 std_idx = len(df) // 4 # 你可以根据需求调整这个值,越大抽样范围越广 # 生成足够多的正态分布索引值(多生成一些避免重复) indices = rng.normal(loc=mid_idx, scale=std_idx, size=20) # 转成整数索引 indices = np.round(indices).astype(int) # 过滤掉超出索引范围的,再去重 valid_indices = np.unique([idx for idx in indices if 0 <= idx < len(df)]) # 取前10个有效索引(如果不够可以再生成,这里假设数量足够) sampled_indices = valid_indices[:10] # 根据索引抽取样本 sampled_df = df.iloc[sampled_indices]
两种方法都能实现正态分布抽样,你可以根据自己的需求选:如果是想基于数据列的分布来抽样,选方法一;如果是想围绕某个位置(比如中间行)来抽样,选方法二~
备注:内容来源于stack exchange,提问作者pjercic
相关产品推荐
相关产品推荐

