根据列值和其他列更新 Pandas 单元格

3

我希望根据一个列中的值更新多个列;使用循环虽然容易实现,但当有许多列和行时,我的应用程序处理时间太长。有什么更优雅的方法来获取每个字母的所需计数?

期望输出:

   Things         count_A     count_B    count_C     count_D
['A','B','C']         1            1         1          0
['A','A','A']         3            0         0          0
['B','A']             1            1         0          0
['D','D']             0            0         0          2
2个回答

3

最优雅的肯定是来自sklearn的CountVectorizer。

我会先展示它的工作原理,然后将所有步骤合并到一行中,这样您就可以看到它有多优雅。

首先,我们将一步一步地完成:

让我们创建一些数据。

raw = ['ABC', 'AAA', 'BA', 'DD']

things = [list(s) for s in raw]

然后读取一些包并初始化计数向量化器。
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd

cv = CountVectorizer(tokenizer=lambda doc: doc, lowercase=False)

接下来,我们生成一个计数矩阵。
matrix = cv.fit_transform(things)

names = ["count_"+n for n in cv.get_feature_names()]

保存为数据框

df = pd.DataFrame(data=matrix.toarray(), columns=names, index=raw)

生成如下数据框:

    count_A count_B count_C count_D
ABC 1   1   1   0
AAA 3   0   0   0
BA  1   1   0   0
DD  0   0   0   2

简洁版本:

将所有内容放在一行上

df = pd.DataFrame(data=cv.fit_transform(things).toarray(), columns=["count_"+n for n in cv.get_feature_names()], index=raw)

时间:

您提到您正在处理一个相当大的数据集,因此我使用了%%timeit函数来给出时间估计。

@piRSquared之前的回答(看起来非常好!)

pd.concat([s, s.apply(lambda x: pd.Series(x).value_counts()).fillna(0)], axis=1)
< p > 100 次循环,最佳结果 3 毫秒每次循环

我的答案:

pd.DataFrame(data=cv.fit_transform(things).toarray(), columns=["count_"+n for n in cv.get_feature_names()], index=raw)

1000次循环,3次中的最佳结果:每次循环1.08毫秒

经过我的测试,CountVectorizer 大约快了3倍。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接