从产品ID关联的12位类目提取多级父类目并统计出现次数
基于Pandas的多级类目提取与统计实现方案
嘿,我刚好处理过类似的需求,给你分享几个实用的Python实现思路,都是用Pandas来搞定的,毕竟咱们日常操作DataFrame用它最顺手了~
首先先明确下需求逻辑:你的12位类目编码应该是按层级递进的(比如前2位一级类目、前4位二级,直到12位是最细的末级类目),咱们要做的就是从每个产品的类目编码里拆出所有上级类目,然后统计每个层级里各类目出现的次数。
方案一:标准化层级拆分 + 长表统计
这个方案适合层级规则固定的场景(比如每2位一个层级),步骤清晰,容易维护:
import pandas as pd # 先构造你的样例数据 products = [ {'category': 110401010601, 'product': 1000023}, {'category': 110401020601, 'product': 1000024}, {'category': 110402010601, 'product': 1000025}, {'category': 120101010101, 'product': 1000026} ] df = pd.DataFrame(products) # 1. 把数字类型的类目编码转成字符串,方便按位截取 df['category_str'] = df['category'].astype(str) # (如果有长度不足12位的编码,记得补前导零:df['category_str'] = df['category_str'].str.pad(12, side='left', fillchar='0')) # 2. 生成各级父类目列(这里假设每2位一个层级,共6级,可根据实际调整) level_names = ['level1', 'level2', 'level3', 'level4', 'level5', 'level6'] for idx, level in enumerate(level_names, 1): # 每级取前2*idx位字符 df[level] = df['category_str'].str[:2*idx] # 3. 把宽表转成长表,方便后续分组统计 melted_df = df.melt( id_vars=['product'], value_vars=level_names, var_name='category_level', value_name='category_code' ) # 4. 按层级+类目编码分组,统计出现次数 count_result = melted_df.groupby(['category_level', 'category_code']).size().reset_index(name='count') print(count_result)
运行后你会得到一个包含层级、类目编码、出现次数的DataFrame,非常直观。
方案二:自定义层级位置(更灵活)
如果你的类目层级不是固定每2位划分(比如有的层级是3位、有的是2位),可以自定义截取位置,适配性更强:
import pandas as pd df = pd.DataFrame(products) df['category_str'] = df['category'].astype(str).str.pad(12, side='left', fillchar='0') # 自定义每个层级的截取终点位置(比如第2、5、7、10、12位,根据你的实际规则调整) cut_positions = [2, 5, 7, 10, 12] level_names = [f'level{i+1}' for i in range(len(cut_positions))] # 生成各级类目列 for pos, level in zip(cut_positions, level_names): df[level] = df['category_str'].str[:pos] # 后续统计和方案一一样 melted_df = df.melt(id_vars=['product'], value_vars=level_names, var_name='category_level', value_name='category_code') count_result = melted_df.groupby(['category_level', 'category_code']).size().reset_index(name='count')
简化版:直接统计所有类目出现次数
如果你不需要保留产品和层级的对应关系,只是想快速统计所有各级类目的总出现次数,可以用更简洁的方式:
import pandas as pd from collections import Counter df = pd.DataFrame(products) df['category_str'] = df['category'].astype(str).str.pad(12, side='left', fillchar='0') # 定义层级截取位置 cut_positions = [2,4,6,8,10,12] all_categories = [] # 遍历每个编码,提取所有上级类目 for code in df['category_str']: for pos in cut_positions: all_categories.append(code[:pos]) # 统计次数并转成DataFrame count_result = pd.DataFrame(Counter(all_categories).items(), columns=['category_code', 'count']) # 可选:添加层级列 count_result['category_level'] = count_result['category_code'].apply(lambda x: len(x)//2)
一些注意事项
- 如果类目编码存在非12位的情况,一定要先做补零处理,避免截取错误;
- 层级划分规则要和业务方确认清楚,比如有的类目是前3位一级、前6位二级,调整
cut_positions即可; - 如果数据量特别大(比如百万级以上),可以考虑用
str.slice代替str[:pos],性能会更好一点。
内容的提问来源于stack exchange,提问作者Matthias
相关产品推荐
相关产品推荐

