如何用Pandas实现R data.table分组重复向量至指定长度的功能
Pandas复现R data.table分组重复向量至组内长度的功能
要在Pandas中实现R data.table里test[, period := rep(q, length.out = .N), by =c('IDx','IDy')]的效果——按IDx和IDy分组,将指定向量q循环重复填充至每个组的所有行,长度匹配组内记录数,以下是两种可行方案:
方案一:使用groupby.transform(推荐)
transform方法会对每个分组执行函数,并返回与原DataFrame行数一致的结果,完美适配生成新列的需求:
import pandas as pd # 构造测试数据 q = [1, 2, 3] valuesX = ['42'] * 5 + ['76'] * 3 + ['43'] * 3 + ['5'] * 2 valuesY = ['A'] * 5 + ['A'] * 3 + ['B'] * 3 + ['C'] * 2 test = pd.DataFrame({'IDx': valuesX, 'IDy': valuesY}) # 定义分组内生成重复序列的函数 def generate_period(group): group_len = len(group) seq_len = len(q) # 计算完整重复次数和剩余元素数 repeat_times, remainder = divmod(group_len, seq_len) # 拼接生成对应长度的序列 return q * repeat_times + q[:remainder] # 按分组生成period列 test['period'] = test.groupby(['IDx', 'IDy']).transform(generate_period)
执行后得到的结果与R的输出完全一致:
IDx IDy period 0 42 A 1 1 42 A 2 2 42 A 3 3 42 A 1 4 42 A 2 5 76 A 1 6 76 A 2 7 76 A 3 8 43 B 1 9 43 B 2 10 43 B 3 11 5 C 1 12 5 C 2
方案二:使用itertools.cycle简化循环逻辑
借助itertools.cycle可以快速生成循环序列,再截取对应长度的元素:
import pandas as pd from itertools import cycle # 构造测试数据(同方案一) q = [1, 2, 3] valuesX = ['42'] * 5 + ['76'] * 3 + ['43'] * 3 + ['5'] * 2 valuesY = ['A'] * 5 + ['A'] * 3 + ['B'] * 3 + ['C'] * 2 test = pd.DataFrame({'IDx': valuesX, 'IDy': valuesY}) # 分组生成循环序列并展开 test['period'] = ( test.groupby(['IDx', 'IDy']) .apply(lambda g: list(cycle(q))[:len(g)]) .explode() .reset_index(drop=True) )
为什么之前的尝试未成功?
- cumcount方法:
cumcount()+1生成的是组内连续递增的序号(如5行组会生成1,2,3,4,5),而非循环重复指定向量,不符合需求。 - 自定义apply函数:直接在函数中修改全局的
test['t']会导致不同分组的结果相互覆盖;且分组仅按IDx,未包含IDy,不符合原需求的分组逻辑。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

