如何对存储字符串数组的DataFrame实现Count Vectorization计数向量化
计数向量化实现方案
问题背景
现有存储分词后单词列表的DataFrame df1,结构示例:
words_separated 0 [lorem, ipsum] 1 [dolor, sit, amet] 2 [lorem, ipsum, dolor, sit, lorem]
需要生成行与原表一一对应、列为所有唯一单词、单元格值为对应行单词出现次数的计数向量化结果df2。之前尝试MultiLabelBinarizer仅能返回单词是否存在的0/1二值,无法统计重复出现次数,无法满足需求。
可用实现方法
方法1:纯Pandas实现(无额外依赖,逻辑直观)
通过explode展开每行的单词列表,保留原行索引后用交叉表统计次数,不需要额外引入机器学习库:
import pandas as pd # 展开每行的单词列表,保留原行索引 exploded_tokens = df1["words_separated"].explode() # 按原行索引、单词两个维度交叉计数 df2 = pd.crosstab(index=exploded_tokens.index, columns=exploded_tokens)
运行后输出结果完全匹配计数需求,可根据需要手动调整列顺序对齐示例格式。
方法2:使用sklearn CountVectorizer(适合大规模数据集,性能更好)
CountVectorizer是sklearn内置的专门用于文本计数向量化的工具,由于输入已经是分好词的单词列表,不需要内置分词逻辑,指定自定义analyzer直接返回输入即可:
import pandas as pd from sklearn.feature_extraction.text import CountVectorizer # 初始化计数向量器,跳过内置分词步骤 cv = CountVectorizer(analyzer=lambda token_list: token_list) # 拟合转换得到计数稀疏矩阵 count_matrix = cv.fit_transform(df1["words_separated"]) # 转换为DataFrame,保留原表索引,列名为所有去重后的单词 df2 = pd.DataFrame( count_matrix.toarray(), columns=cv.get_feature_names_out(), index=df1.index )
该方法底层用稀疏矩阵存储计算结果,数据量较大时内存占用和计算速度明显优于纯Pandas方法。
方法3:逐行Counter统计(仅适合极小数据集,不推荐大数据量使用)
如果数据量非常小,也可以用collections.Counter逐行统计单词出现次数,再拼接为DataFrame:
import pandas as pd from collections import Counter # 逐行生成单词计数字典,空值填0后转整数类型 df2 = pd.DataFrame(df1["words_separated"].apply(Counter).tolist()).fillna(0).astype(int)
该方法逐行循环处理,数据量超过1万行后性能会明显下降。
说明:
MultiLabelBinarizer的设计定位是多标签二值编码,仅判断标签是否存在,本身不支持重复标签的计数逻辑,不适合该场景。
内容的提问来源于stack exchange,提问作者Sayyor Y
相关产品推荐
相关产品推荐

