DataFrame按Name分组,每5行/50ft间隔拆分,提取D列首、次众数
解决方案
使用Pandas的分组功能结合自定义函数实现,代码如下:
import pandas as pd # 构造示例DataFrame data = { 'Name': ['cat']*9 + ['dog']*10, 'A': [0,10,20,30,40,50,60,70,80,0,10,20,30,40,50,60,70,80,90], 'B': [10,20,30,40,50,60,70,80,90,10,20,30,40,50,60,70,80,90,100], 'C': [1,2,3,5,8,9,59,11,60,56,69,89,50,52,66,67,47,48,89], 'D': [23,22,23,22,22,27,24,24,27,23,23,22,23,22,27,24,27,24,27], 'first Majority': ['']*19, 'second Majority': ['']*19 } df = pd.DataFrame(data) def fill_majorities(subgroup): # 按频次排序,频次相同保留首次出现顺序 count_rank = subgroup['D'].value_counts(ascending=False, sort=True) mode_list = count_rank.index.tolist() # 提取首、次众数 first_mode = mode_list[0] if len(mode_list) >= 1 else None second_mode = mode_list[1] if len(mode_list) >= 2 else None # 仅在子组首行填充值 subgroup.iloc[0, subgroup.columns.get_loc('first Majority')] = first_mode subgroup.iloc[0, subgroup.columns.get_loc('second Majority')] = second_mode return subgroup # 按Name分组,再按每5行拆分,应用函数 final_df = df.groupby('Name', group_keys=False).apply( lambda group: group.groupby(lambda idx: idx // 5).apply(fill_majorities) ).reset_index(drop=True) print(final_df)
代码说明
- 构造测试数据:还原题目中的DataFrame,初始时将
first Majority和second Majority列置空。 - 自定义函数
fill_majorities:- 用
value_counts统计D列元素频次,sort=True保证频次高的在前,频次相同时保留元素首次出现的顺序(满足题目"次数相等取先出现"的规则)。 - 从排序后的索引中提取首、次众数,仅在子组的第一行填入对应列。
- 用
- 分组拆分逻辑:
- 先按
Name分组,得到每个动物的子数据集。 - 对每个子数据集,通过
groupby(lambda idx: idx//5)实现每5行拆分:行索引idx除以5取整,0-4行归为一组,5-9行归为下一组,不足5行自动单独成组。 - 对每个拆分后的子组应用填充函数,最后重置索引得到结果。
- 先按
内容的提问来源于stack exchange,提问作者Taiwo
相关产品推荐
相关产品推荐

