Pandas分组与转换:统一分组内最频繁Name字段值
解决分组内将Name字段替换为频次最高值的问题
问题背景
我们有一个包含大小写不一致Name字段的数据集,示例数据如下:
| 序号 | Name | Value | id |
|---|---|---|---|
| 0 | Alegro | 0.850122 | alegro |
| 1 | Alegro | 0.447362 | alegro |
| 2 | AlEgro | 0.711295 | alegro |
| 3 | ALEGRO | 0.123761 | alegro |
| 4 | alegRo | 0.273111 | alegro |
| 5 | ALEGRO | 0.564893 | alegro |
| 6 | ALEGRO | 0.276369 | alegro |
| 7 | ALEGRO | 0.526434 | alegro |
| 8 | ALEGRO | 0.924014 | alegro |
| 9 | ALEGrO | 0.629207 | alegro |
| 10 | Belagio | 0.834231 | belagio |
| 11 | BElagio | 0.788357 | belagio |
| 12 | Belagio | 0.092156 | belagio |
| 13 | BeLaGio | 0.810275 | belagio |
可以通过以下代码复现该数据集:
import numpy as np import pandas as pd data = {'Name': ['Alegro', 'Alegro', 'AlEgro', 'ALEGRO', 'alegRo', 'ALEGRO','ALEGRO', 'ALEGRO','ALEGRO','ALEGrO', 'Belagio','BElagio', 'Belagio', 'BeLaGio'], 'Value': np.random.random(14)} df = pd.DataFrame(data) df['id'] = df.Name.str.lower()
执行分组统计各Name频次后:
df.groupby('id').Name.value_counts()
得到结果:
id Name alegro ALEGRO 5 Alegro 2 ALEGrO 1 AlEgro 1 alegRo 1 belagio Belagio 2 BElagio 1 BeLaGio 1
我们的需求是:为每个id分组选取出现频次最高的Name值,替换原Name字段,最终得到每个分组内统一使用高频Name的DataFrame。
实现方案
方法1:使用groupby + transform + mode
Pandas的mode()方法可以直接获取每组的众数(即频次最高的值),结合transform可以将结果映射回原DataFrame的每一行:
# 为每个id分组获取Name的众数(取第一个众数,避免多众数情况) df['Name'] = df.groupby('id')['Name'].transform(lambda x: x.mode()[0])
解释:
groupby('id')['Name']按id分组处理Name字段transform保证返回结果的长度和原DataFrame一致x.mode()[0]获取每组的第一个众数,当存在多个频次相同的最高值时,取最先出现的那个
方法2:使用value_counts构建映射字典,再替换
先统计每个id对应的高频Name,构建字典后用map替换:
# 统计每个id的最高频Name,构建映射字典 name_mapping = df.groupby('id')['Name'].value_counts().groupby('id').head(1).reset_index(level=0, drop=True).to_dict() # 替换原Name字段 df['Name'] = df['id'].map(name_mapping)
解释:
df.groupby('id')['Name'].value_counts()得到每组各Name的频次groupby('id').head(1)取出每个id分组内频次最高的那一行reset_index(level=0, drop=True)去掉id索引,得到id到高频Name的映射- 最后用
df['id'].map(name_mapping)将每个id对应的高频Name替换原字段
验证结果
执行上述任意一种方法后,查看结果:
print(df[['Name', 'id']])
会得到:
Name id 0 ALEGRO alegro 1 ALEGRO alegro 2 ALEGRO alegro 3 ALEGRO alegro 4 ALEGRO alegro 5 ALEGRO alegro 6 ALEGRO alegro 7 ALEGRO alegro 8 ALEGRO alegro 9 ALEGRO alegro 10 Belagio belagio 11 Belagio belagio 12 Belagio belagio 13 Belagio belagio
内容的提问来源于stack exchange,提问作者And_R
相关产品推荐
相关产品推荐

