You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas:按ID聚合获取animal列最常见字符串(同计数取最后值)

解决方案:按ID聚合并获取出现频率最高/最后出现的Animal值

我来帮你搞定这个需求,下面提供两种基于Pandas的实现方案,都能完美匹配你的期望输出:

方法一:自定义分组函数(直观易懂)

这种方法逻辑清晰,适合刚接触Pandas分组操作的场景,每一步都能明确看到处理过程:

首先先构造你的示例数据集:

import pandas as pd

# 构造示例数据
data = {
    'id': [1,1,1,2,3,4,5,5],
    'animal': ['dog','dog','cat','cat','dog','fish','dog','cat'],
    'date': ['2018-01-01','2018-01-02','2018-01-03','2018-01-01','2018-01-01','2018-01-01','2018-01-01','2018-01-02']
}
df = pd.DataFrame(data)
# 建议把date转为datetime类型,确保排序准确
df['date'] = pd.to_datetime(df['date'])

然后定义处理每个分组的自定义函数,再应用到分组上:

def get_target_animal(group):
    # 先按日期排序,保证最新的记录在分组末尾
    sorted_group = group.sort_values('date')
    # 统计当前ID下每个动物的出现频率
    animal_counts = sorted_group['animal'].value_counts()
    # 获取最高出现频率
    max_freq = animal_counts.max()
    # 筛选出所有达到最高频率的动物候选
    candidates = animal_counts[animal_counts == max_freq].index.tolist()
    
    # 从分组末尾往前找第一个候选动物(也就是最后出现的那个)
    for animal in reversed(sorted_group['animal']):
        if animal in candidates:
            return animal

# 按ID分组应用函数,整理成结果格式
result = df.groupby('id')['animal'].apply(get_target_animal).reset_index()
result.columns = ['id', 'animal']
print(result)

运行后就能得到你想要的输出:

id animal
0   1    dog
1   2    cat
2   3    dog
3   4   fish
4   5    cat

方法二:基于排名的高效实现(适合大数据集)

如果你的数据集很大,上面的遍历方法效率会偏低,这种利用rank和排序的方法更高效:

import pandas as pd

# 构造并预处理数据
data = {
    'id': [1,1,1,2,3,4,5,5],
    'animal': ['dog','dog','cat','cat','dog','fish','dog','cat'],
    'date': ['2018-01-01','2018-01-02','2018-01-03','2018-01-01','2018-01-01','2018-01-01','2018-01-01','2018-01-02']
}
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])

# 1. 给每条记录添加当前ID下对应动物的出现次数
df['animal_freq'] = df.groupby(['id', 'animal'])['animal'].transform('count')
# 2. 给每个(ID,动物)组内的记录按日期逆序排名(最后出现的排第1)
df['last_appear_rank'] = df.groupby(['id', 'animal'])['date'].rank(ascending=False, method='first')

# 3. 按ID升序、频率降序、逆序排名升序排序,每个ID取第一条
result = df.sort_values(
    by=['id', 'animal_freq', 'last_appear_rank'],
    ascending=[True, False, True]
).groupby('id').first().reset_index()[['id', 'animal']]

print(result)

这个方法的核心逻辑是:

  • 先计算每个(ID,动物)组合的出现次数
  • 再给每个组合内的记录按日期逆序排名,确保最后出现的记录排名最高
  • 最后通过排序优先级(频率优先,频率相同则最后出现的优先),每个ID取第一条即可得到目标结果

内容的提问来源于stack exchange,提问作者Auren Ferguson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:40:46