如何为DataFrame各年份分组生成无重复的随机日?
为DataFrame分组生成不重复随机日的解决方案
问题描述
我需要给DataFrame的每个年份分组生成不重复的随机日,因此必须设置replace=False避免重复值。另外我的年份列表包含超过365个年份,无法直接给整个DataFrame添加随机数列(否则无重复抽样会无法生成足够样本)。尝试了agg、aggregate、apply和transform方法后,当前代码得到的同组内随机日完全相同,不符合需求。
当前尝试代码
import pandas as pd import numpy as np years = pd.DataFrame({"year": [1,1,2,2,2,3,3,4,4,4,4]}) years["day"] = 0 grouped = years.groupby("year")["day"] grouped.transform(lambda x: np.random.choice(366, replace=False))
当前结果
0 8 1 8 2 319 3 319 4 319 5 149 6 149 7 130 8 130 9 130 10 130 Name: day, dtype: int64
期望结果
0 8 1 16 2 119 3 321 4 333 5 4 6 99 7 30 8 129 9 224 10 355 Name: day, dtype: int64
解决方案
问题根源是原transform的lambda仅生成单个随机数,然后广播到整个分组行。要实现同组内每行随机日不同,需针对每个分组的行数生成对应长度的无重复随机样本。
方法1:使用apply生成对应长度序列
import pandas as pd import numpy as np years = pd.DataFrame({"year": [1,1,2,2,2,3,3,4,4,4,4]}) years["day"] = years.groupby("year")["year"].apply( lambda x: np.random.choice(366, size=len(x), replace=False) )
方法2:修正transform逻辑
transform要求返回结果与原分组长度一致,因此在lambda中根据分组长度生成对应数量的无重复随机数:
years["day"] = grouped.transform(lambda x: np.random.choice(366, size=len(x), replace=False))
两种方法都能实现同组内随机日不重复的需求,同时保证每个分组的抽样是无重复的。
内容的提问来源于stack exchange,提问作者Bowser
相关产品推荐
相关产品推荐

