如何在Pandas中按出现频率保留Top3客户名称并将其余标记为Other
解决DataFrame中保留Top3高频客户名称的问题
嘿,我来帮你搞定这个问题!你的思路方向是对的,但代码里的loc语法出了问题,咱们一步步修正:
问题分析
你想要实现的是:仅保留customerId出现频率排名前三的客户原名称,其余统一标记为"Other",核心是筛选出Top3的客户ID,再批量赋值。
错误代码的问题
你写的这行代码语法完全错误:
df.loc[df['customerId']].isin(v.index[v.gt(2)]), 'name2'] = df['name']
正确的loc用法应该是df.loc[筛选条件, 目标列名],你把isin的位置和括号结构搞混了。
正确实现方案
方法1:按频次阈值筛选(和你的原思路匹配)
如果你想保留出现次数>2的客户(刚好对应示例里的Top3),可以这么写:
import pandas as pd d = { "customerId": [1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 5], "name": ['max', 'max', 'lisa', 'lisa', 'lisa', 'lisa', 'michael', 'michael', 'michael', 'power', 'wind', 'wind', 'wind', 'wind', 'wind'] } df = pd.DataFrame(data=d) # 统计customerId的出现频次 v = df['customerId'].value_counts() # 筛选出出现次数>2的customerId top_ids = v.index[v.gt(2)] # 初始化name2列为"Other" df['name2'] = 'Other' # 对符合条件的行,将name2赋值为原name的值 df.loc[df['customerId'].isin(top_ids), 'name2'] = df['name'] print(df)
方法2:更通用的Top3排名筛选(推荐)
如果需求是严格取出现频率排名前三的客户(不管频次多少),用nlargest(3)更准确:
import pandas as pd d = { "customerId": [1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 5], "name": ['max', 'max', 'lisa', 'lisa', 'lisa', 'lisa', 'michael', 'michael', 'michael', 'power', 'wind', 'wind', 'wind', 'wind', 'wind'] } df = pd.DataFrame(data=d) # 统计频次并直接取排名前三的customerId top3_ids = df['customerId'].value_counts().nlargest(3).index df['name2'] = 'Other' df.loc[df['customerId'].isin(top3_ids), 'name2'] = df['name'] print(df)
验证输出
运行上面的代码后,你会得到和期望完全一致的结果:
| 行号 | customerId | name | name2 |
|---|---|---|---|
| 0 | 1 | max | Other |
| 1 | 1 | max | Other |
| 2 | 2 | lisa | lisa |
| 3 | 2 | lisa | lisa |
| 4 | 2 | lisa | lisa |
| 5 | 2 | lisa | lisa |
| 6 | 3 | michael | michael |
| 7 | 3 | michael | michael |
| 8 | 3 | michael | michael |
| 9 | 4 | power | Other |
| 10 | 5 | wind | wind |
| 11 | 5 | wind | wind |
| 12 | 5 | wind | wind |
| 13 | 5 | wind | wind |
| 14 | 5 | wind | wind |
内容的提问来源于stack exchange,提问作者Test
相关产品推荐
相关产品推荐

