如何将DataFrame中子实例列归类为更少分组?附示例数据
实现子类别到大分组的归类方案
嘿,这个需求在数据处理里太常见了!咱们可以通过映射字典结合Pandas的map()或replace()方法,轻松把零散的子类别归为更少的大分组。我结合你给出的示例数据,给你一步步演示具体操作:
首先先把你的示例DataFrame创建出来:
import pandas as pd import numpy as np df = pd.DataFrame({ 'a':np.random.randn(60), 'b':np.random.choice( [5,7,np.nan], 60), 'c':np.random.choice( ['panda', 'elephant', 'python', 'anaconda', 'shark', 'clown fish'], 60), 'e':np.tile( range(20), 3 ) })
一、字符串子类别分组(以列c为例)
假设我们想把列c的6个子类别归为3个大分组:
- 陆地哺乳动物:panda、elephant
- 蛇类:python、anaconda
- 海洋生物:shark、clown fish
方法1:用映射字典 + map()(最推荐)
先定义子类别到大分组的映射关系,再用map()批量转换:
# 定义映射字典,key是子类别,value是目标大分组 category_map = { 'panda': '陆地哺乳动物', 'elephant': '陆地哺乳动物', 'python': '蛇类', 'anaconda': '蛇类', 'shark': '海洋生物', 'clown fish': '海洋生物' } # 新增一列存储分组结果 df['c_grouped'] = df['c'].map(category_map)
map()会遍历列c的每个元素,精准匹配字典中的key并替换为对应的value。如果遇到字典里没覆盖的子类别,会返回NaN,可以用fillna()统一处理:
# 把未匹配到的子类别归为“其他” df['c_grouped'] = df['c'].map(category_map).fillna('其他')
方法2:用replace()实现批量替换
replace()也能实现相同效果,语法和map()几乎一致,适合习惯用这个方法的场景:
df['c_grouped'] = df['c'].replace(category_map)
如果你的子类别有规律(比如包含特定关键词),还可以结合正则表达式批量替换,比如所有带“fish”的都归为海洋生物:
# 正则匹配含"fish"的子类别 df['c_grouped'] = df['c'].replace(r'.*fish.*', '海洋生物', regex=True)
二、数值型列的分组技巧(以列b为例)
你的列b是数值+缺失值的结构,我们可以用np.where或pd.cut来分组:
针对离散数值/缺失值分组
比如把5、7归为“有效数值”,NaN归为“缺失值”:
df['b_grouped'] = np.where(df['b'].isna(), '缺失值', '有效数值')
针对连续数值分桶(以列a为例)
如果是像列a这样的连续随机数,想分成“低”“中”“高”三个区间,可以用pd.cut():
# 按等频分3桶,自定义标签 df['a_grouped'] = pd.cut(df['a'], bins=3, labels=['低', '中', '高'])
也可以手动指定区间边界:
# 自定义区间:(-∞, -0.5], (-0.5, 0.5], (0.5, +∞) df['a_grouped'] = pd.cut(df['a'], bins=[-np.inf, -0.5, 0.5, np.inf], labels=['低', '中', '高'])
三、额外注意事项
- 如果子类别数量特别多,手动写映射字典麻烦,可以先提取唯一值再批量赋值:
# 获取列c的所有唯一子类别 unique_subcats = df['c'].unique() # 然后逐个对应大分组,比如用循环或字典推导式 - 如果子类别存在拼写差异(比如"clownfish"和"clown fish"),可以用模糊匹配库(如
fuzzywuzzy)来实现近似映射,不过需要额外安装依赖。
最后可以用value_counts()验证分组结果是否正确:
print(df['c_grouped'].value_counts())
内容的提问来源于stack exchange,提问作者user8970863
相关产品推荐
相关产品推荐

