大数据量DataFrame中添加字符出现次数排序列的高效实现
解决方案
首先纠正你之前的错误:collections.Counter(df['item'])是统计整个列中各字符串的出现次数,而非单个字符串内部的字符计数,这是你没得到预期结果的核心原因。
针对大数据量的高效需求,提供两种可行方案:
方案一:简洁版(适合中小规模数据)
利用apply结合Counter,逐行处理每个字符串并整理计数结果:
import pandas as pd from collections import Counter # 构造原始DataFrame df = pd.DataFrame({ 'Item': ['ABABCBF', 'ABABCGH', 'ABABEFR', 'ABABFBF', 'ABACTC3'] }) def process_string(s): # 统计字符出现次数并按降序排序 sorted_counts = sorted(Counter(s).values(), reverse=True) # 补全到5个元素,不足的用NaN填充 return sorted_counts + [pd.NA] * (5 - len(sorted_counts)) # 生成计数列并合并到原DataFrame count_cols = df['Item'].apply(lambda x: pd.Series(process_string(x), index=['o1', 'o2', 'o3', 'o4', 'o5'])) result_df = pd.concat([df, count_cols], axis=1)
方案二:高效版(适合超大规模数据)
利用pandas的矢量化分组操作,避免逐行循环,性能更优:
import pandas as pd # 构造原始DataFrame df = pd.DataFrame({ 'Item': ['ABABCBF', 'ABABCGH', 'ABABEFR', 'ABABFBF', 'ABACTC3'] }) # 1. 将每个字符串拆分为单个字符,展开为多行 char_expanded = df.assign(char=df['Item'].str.split('')).explode('char') # 2. 按Item和字符分组,统计出现次数 char_counts = char_expanded.groupby(['Item', 'char']).size().reset_index(name='count') # 3. 对每个Item的计数按降序排序,生成排名(1-5) char_counts['rank'] = char_counts.groupby('Item')['count'].rank(ascending=False, method='first').astype(int) char_counts = char_counts[char_counts['rank'] <= 5] # 4. 转换为宽表格式,匹配o1-o5列 wide_counts = char_counts.pivot( index='Item', columns='rank', values='count' ).rename(columns={i: f'o{i}' for i in range(1,6)}) # 5. 合并到原DataFrame result_df = df.merge(wide_counts, on='Item', how='left')
结果验证
运行上述代码后,result_df将与你期望的格式完全一致:
Item o1 o2 o3 o4 o5 0 ABABCBF 3.0 2.0 1.0 1.0 <NA> 1 ABABCGH 2.0 2.0 1.0 1.0 1.0 2 ABABEFR 2.0 2.0 1.0 1.0 1.0 3 ABABFBF 3.0 2.0 2.0 <NA> <NA> 4 ABACTC3 2.0 2.0 1.0 1.0 1.0
注:若需要显示
null而非<NA>,可将代码中的pd.NA替换为None。
内容的提问来源于stack exchange,提问作者SkyBest I
相关产品推荐
相关产品推荐

