如何为含特定字符串列表的每个唯一元素创建n个随机分层样本(嵌套循环?)
分层抽样实现方案
当然可以用嵌套循环来实现你的分层抽样需求,不过先给你理清楚整体思路,再给你具体的代码示例,还有针对百万级大数据的优化建议~
一、基础嵌套循环实现思路
核心逻辑是先把数据按城市编码分组,再从每个分组里随机抽取指定数量的样本,嵌套逻辑就体现在「遍历所有城市分组 + 对每个分组内的号码进行抽样」这两步上。
具体步骤:
- 先分组:把主列表里的电话号码按城市编码归类,用字典来存储,键是城市编码,值是对应城市的所有电话号码列表。
- 再抽样:遍历每个城市分组,从组里随机选指定数量的样本,收集到最终的样本列表中。
Python代码示例:
import random # 假设你的mainlist结构是:[[城市编码, 电话号码], ...] mainlist = [["010", "138xxxx1234"], ["021", "139xxxx5678"], ["010", "137xxxx9012"], ...] # 第一步:按城市编码分组 city_phone_groups = {} for city_code, phone_num in mainlist: if city_code not in city_phone_groups: city_phone_groups[city_code] = [] city_phone_groups[city_code].append(phone_num) # 设定每个城市要抽取的样本数量,比如每个城市抽5个 sample_per_city = 5 final_stratified_sample = [] # 第二步:嵌套逻辑实现抽样(外层遍历分组,内层完成抽样) for city_code, phone_list in city_phone_groups.items(): # 避免城市号码数不足样本量的情况,取两者的最小值 actual_sample_size = min(sample_per_city, len(phone_list)) # 随机抽取不重复的样本 sampled_phones = random.sample(phone_list, actual_sample_size) # 把抽样结果和城市编码组合后加入最终样本 final_stratified_sample.extend([[city_code, phone] for phone in sampled_phones])
这里的嵌套逻辑其实是外层循环遍历所有城市分组,而random.sample内部帮我们完成了对组内元素的随机选取,如果你想手动写内层循环实现抽样(比如不使用内置函数),也是可以的,不过random.sample已经足够高效且简洁,没必要重复造轮子。
二、百万级数据的高效优化方案
因为你的数据是百万级别的,纯Python循环虽然能跑,但效率可能不够,推荐用pandas来处理,它的分组和抽样都是经过底层优化的,处理大数据会快很多:
import pandas as pd # 将主列表转换为DataFrame phone_df = pd.DataFrame(mainlist, columns=["city_code", "phone_num"]) # 按城市编码分组,每个组抽取指定数量的样本 sample_per_city = 5 # 处理样本量超过组内元素的情况,同时设置random_state保证抽样可复现 stratified_sample_df = phone_df.groupby("city_code").apply( lambda group: group.sample(n=min(sample_per_city, len(group)), random_state=42) ) # 如果需要转回列表格式 final_stratified_sample = stratified_sample_df.reset_index(drop=True).values.tolist()
关键注意事项
- 必须处理城市号码数量小于指定样本量的情况,否则会触发抽样报错,用
min()函数就能轻松规避。 - 如果需要可重复的抽样结果,记得给抽样函数加上
random_state参数(比如random_state=42)。 - 如果内存不足以一次性加载百万级数据,可以考虑分块读取数据,逐步完成分组和抽样,避免内存溢出。
内容的提问来源于stack exchange,提问作者Sven
相关产品推荐
相关产品推荐

