影刀RPA 数据抽样与随机选取
作者:林焱
什么情况用什么
数据量太大需要抽样分析、随机抽取N条记录做测试、从客户名单中随机选取中奖者、按比例分层抽样做质检。在影刀RPA里用pandas的sample函数可以轻松实现随机抽样,还支持按权重抽样和分层抽样。
适用场景:数据抽样分析、随机抽查质检、抽奖活动、测试数据生成、大数据量快速预览。
怎么做
基础随机抽样
拼多多店群自动化报活动上架!
importpandasaspd df=pd.read_excel(r"C:\Data\orders.xlsx")# 随机抽取10条sample_10=df.sample(n=10)# 随机抽取10%sample_10pct=df.sample(frac=0.1)# 随机抽取80%(用于训练集)train=df.sample(frac=0.8)# 剩余20%作为测试集test=df.drop(train.index)# 可重复实验:设置随机种子sample=df.sample(n=10,random_state=42)# 每次运行结果相同分层抽样
defstratified_sample(df,stratum_col,n=None,frac=None):""" 分层抽样:每个分组按比例抽样 stratum_col: 分层依据列 n: 每组抽取数量 frac: 每组抽取比例 """samples=[]forstratum_val,groupindf.groupby(stratum_col):ifnisnotNone:# 每组抽n条(不足则全部取)sample_n=min(n,len(group))sampled=group.sample(n=sample_n,random_state=42)eliffracisnotNone:sampled=group.sample(frac=frac,random_state=42)samples.append(sampled)result=pd.concat(samples).reset_index(drop=True)returnresult# 使用:每个地区抽5条stratified=stratified_sample(df,stratum_col='地区',n=5)# 每个地区抽10%stratified=stratified_sample(df,stratum_col='地区',frac=0.1)按权重抽样
# 按权重抽样:金额大的被抽中概率更高df['权重']=df['金额']/df['金额'].sum()# 金额占比作为权重weighted_sample=df.sample(n=20,weights='权重',random_state=42)# 自定义权重# VIP客户被抽中的概率是普通客户的3倍df['权重']=df['客户等级'].map({'VIP':3,'普通':1})weighted_sample=df.sample(n=20,weights='权重',random_state=42)随机选取应用场景
# 1. 随机抽奖deflottery_draw(participants_file,winners_count,output_file):"""随机抽奖"""df=pd.read_excel(participants_file)# 确保有唯一标识if'工号'notindf.columns:df['序号']=range(1,len(df)+1)key_col='序号'else:key_col='工号'# 随机抽取winners=df.sample(n=winners_count,random_state=None)# 不设种子,真随机winners['中奖等级']=['一等奖']*min(1,len(winners))+\['二等奖']*min(3,max(0,len(winners)-1))+\['三等奖']*max(0,len(winners)-4)winners.to_excel(output_file,index=False)print(f"参与人数:{len(df)}")print(f"中奖人数:{len(winners)}")print(f"中奖率:{len(winners)/len(df)*100:.2f}%")returnwinners# 2. 质检抽样defquality_check_sample(df,sample_rate=0.05,stratify_col=None):"""质检抽样"""ifstratify_col:# 分层抽样sample=stratified_sample(df,stratify_col,frac=sample_rate)else:# 简单随机抽样sample=df.sample(frac=sample_rate,random_state=42)sample['抽样时间']=pd.Timestamp.now()sample['抽样方式']='分层抽样'ifstratify_colelse'随机抽样'returnsample# 使用:按地区分层抽5%做质检qa_sample=quality_check_sample(df,sample_rate=0.05,stratify_col='地区')qa_sample.to_excel(r"C:\Data\qa_sample.xlsx",index=False)数据快速预览
defquick_preview(df,n=5):"""快速预览大数据"""print(f"总行数:{len(df)}")print(f"总列数:{len(df.columns)}")print(f"\n随机{n}条预览:")print(df.sample(n=min(n,len(df)),random_state=42).to_string())print(f"\n数值列统计:")print(df.describe().round(2))print(f"\n分类列分布:")cat_cols=df.select_dtypes(include=['object']).columnsforcolincat_cols[:3]:print(f"\n{col}:")print(f"{df[col].value_counts().head(5).to_dict()}")# 使用df=pd.read_excel(r"C:\Data\big_data.xlsx")# 10万行quick_preview(df,n=5)影刀RPA抽样流程
【读取Excel文件】→ 全量数据 【执行Python代码】→ 分层抽样 按地区分层,每组抽10% 【写入Excel文件】→ 抽样结果 【输出信息】  总数: 10000 抽样: 1000 分组: 北京200, 上海180, 广州150...有什么坑
坑1:sample(n=)超过总行数
TEMU店群矩阵自动化运营核价报活动
# 问题:只有5行但要抽10行df.sample(n=10)# ValueError: Cannot take a larger sample than population when 'replace=False'# 解决1:用replace=True允许重复抽样df.sample(n=10,replace=True)# 有放回抽样# 解决2:限制数量n=min(10,len(df))df.sample(n=n)坑2:随机种子影响可重复性
# 问题:每次运行结果不同,无法复现df.sample(n=10)# 每次不同# 解决:设置random_statedf.sample(n=10,random_state=42)# 每次相同# 但注意:不同pandas版本可能结果不同# 如果需要严格复现,保存抽样结果到文件坑3:分层抽样比例不均
# 问题:某组只有3条,要抽10%,结果抽0条group.sample(frac=0.1)# 3 * 0.1 = 0.3 → 抽0条# 解决:设最少抽1条defsafe_sample(group,frac,min_n=1):n=max(min_n,int(len(group)*frac))returngroup.sample(n=min(n,len(group)),random_state=42)# 或用ceilimportmath n=math.ceil(len(group)*frac)# 向上取整坑4:抽样后索引乱
# 问题:抽样后索引不连续sample=df.sample(n=10)print(sample.index)# 可能是 3, 7, 15, 22...# 解决:重置索引sample=df.sample(n=10).reset_index(drop=True)坑5:权重抽样权重为0的记录永远抽不到
# 问题:金额为0的记录权重为0,永远抽不到df['权重']=df['金额']# 金额为0的权重为0# 解决:给所有记录一个基础权重df['权重']=df['金额']+0.01# 加一个很小的值# 或者分两步:先按权重抽大部分,再从剩余中随机补