Python实现凭证金额分层随机抽样(Stratified Random Sample)技术问询
Python实现凭证金额分层随机抽样
1. 识别凭证金额所属类别
假设凭证数据存储在DataFrame中,包含amount字段(金额为数值类型,已去除$符号),可通过pandas.cut快速完成类别划分:
import pandas as pd import numpy as np # 模拟大量凭证数据(实际使用时替换为你的数据源) np.random.seed(42) # 固定随机种子保证结果可复现 data = pd.DataFrame({ 'voucher_id': range(1, 10001), 'amount': np.random.uniform(0, 10000, 10000) # 生成0-10000的随机金额 }) # 定义金额区间与对应类别标签 bins = [0, 500, 2000, 5000, float('inf')] labels = ['$0-$500', '$500-$2000', '$2000-$5000', '$5000以上'] # 为每条凭证添加类别标签 data['amount_category'] = pd.cut(data['amount'], bins=bins, labels=labels, include_lowest=True) # 查看分类结果示例 print(data[['voucher_id', 'amount', 'amount_category']].head())
include_lowest=True确保0元凭证被归入第一个区间,若原始金额带$符号,可通过data['amount'] = data['amount'].replace('[\$,]', '', regex=True).astype(float)转换为数值类型。
2. 按总体比例抽取分层样本
根据需求,四类在总体中的占比分别为1%、2%、3%、4%,分两种常见场景实现:
场景A:按总体占比分配总样本量
若需抽取固定总样本量,按比例分配各层样本数(例如总样本量1000,则四类分别抽10、20、30、40个样本):
# 定义各层对应总体的占比 stratum_ratios = { '$0-$500': 0.01, '$500-$2000': 0.02, '$2000-$5000': 0.03, '$5000以上': 0.04 } total_sample_size = 1000 # 自定义总样本量 sampled_data = pd.DataFrame() for category, ratio in stratum_ratios.items(): sample_size = int(total_sample_size * ratio) # 从当前层随机抽取样本 stratum_sample = data[data['amount_category'] == category].sample(n=sample_size, random_state=42) sampled_data = pd.concat([sampled_data, stratum_sample]) sampled_data = sampled_data.reset_index(drop=True) # 输出抽样结果及各层占比 print("抽样样本示例:") print(sampled_data.head()) print("\n抽样样本各层占比:") print(sampled_data['amount_category'].value_counts(normalize=True))
场景B:抽取各层自身数量的对应比例
若需求是从每个层内抽取自身数量的对应比例(例如$0-$500层抽1%的样本,$500-$2000层抽2%的样本):
# 定义各层的抽样比例(针对层内数据量) stratum_ratios = { '$0-$500': 0.01, '$500-$2000': 0.02, '$2000-$5000': 0.03, '$5000以上': 0.04 } sampled_data = pd.DataFrame() for category, ratio in stratum_ratios.items(): stratum_data = data[data['amount_category'] == category] # 确保至少抽取1个样本(若层内数据量不足) sample_size = max(1, int(len(stratum_data) * ratio)) stratum_sample = stratum_data.sample(n=sample_size, random_state=42) sampled_data = pd.concat([sampled_data, stratum_sample]) sampled_data = sampled_data.reset_index(drop=True) # 输出抽样结果及各层抽取数量 print("抽样样本示例:") print(sampled_data.head()) print("\n各层抽取数量:") print(sampled_data['amount_category'].value_counts())
注意事项
- 若某层实际数据量不足以支撑所需样本量,可根据业务需求调整(例如抽取该层全部样本,或修改总样本量)。
内容的提问来源于stack exchange,提问作者Rose Lloyd
相关产品推荐
相关产品推荐

