【问题标题】:count items across all columns using pandas method使用 pandas 方法计算所有列中的项目
【发布时间】:2020-04-10 14:24:12
【问题描述】:

我有这个数据框,我可以使用矢量化器获取每行每个项目的计数。但这适用于单行(例如 col1)。如何将其应用于整个数据框(所有 3 列)?

import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer

shopping_list = [
    ["Apple", "Bread", "Fridge"],
    ["Rice", "Bread", "Milk"],
    ["Apple", "Rice", "Bread"],
    ["Rice", "Milk", "Milk"],
    ["Apple", "Bread", "Milk"],
]

df = pd.DataFrame(shopping_list)
df.columns = ['col1', 'col2', 'col3']

CV = CountVectorizer()
cv_matrix=CV.fit_transform(df['col1'].values)
ndf = pd.SparseDataFrame(cv_matrix)
ndf.columns = CV.get_feature_names()
X = ndf.fillna("0")

单列结果正确:

apple   rice
0   1   0
1   0   1
2   1   0
3   0   1
4   1   0

所有列的预期结果:

    Apple   Rice    Bread   Milk    Fridge
0   1   0   1   0   1
1   0   1   1   1   0
2   1   1   1   0   0
3   0   1   0   2   0
4   1   0   1   1   0

还有其他方法可以获得相同的结果吗?

【问题讨论】:

  • 嗨@shantanuo,答案对你有帮助吗??
  • 你能告诉我为什么python标签与这个问题无关吗?
  • 如果你在数物品,那么牛奶必须是第 4 行中的 2 对吧?
  • 删除了 python 标记,因为我正在寻找仅使用“CountVectorizer”类的解决方案。 ALollz 已经回答了这个问题。他可以使用 sum 而不是 max 来获得第 4 行中的牛奶 2
  • 您的真实数据是否与此相似?您可能会更好地使用不同的数据结构?我相信它已经被提出来了,但我也会鼓励替换那个 SparseDataframe。

标签: scikit-learn countvectorizer


【解决方案1】:

您可以堆叠并获得假人。然后按索引取最大值(sum,如果你想要计数而不是假人)

pd.get_dummies(df.stack()).max(level=0)

   Apple  Bread  Fridge  Milk  Rice
0      1      1       1     0     0
1      0      1       0     1     1
2      1      1       0     0     1
3      0      0       0     1     1
4      1      1       0     1     0

或者,get_dummies 在整个 DataFrame 上使用空白前缀并沿列轴分组。

pd.get_dummies(df, prefix='', prefix_sep='').max(level=0, axis=1)

【讨论】:

  • 使用计数向量化器是否可以获得相同的结果?
  • @shantanuo 也许,但有什么理由不使用那段简单的 pd.SparseDataFrame 已被弃用,所以我会避免依赖它,可能会更好地切换到pd.DataFrame(cv_matrix.toarray())
  • 此步骤是广泛使用 sklearn 模块的复杂脚本的一部分。因此,我更喜欢计数矢量化器而不是通用 pandas 方法。如果太复杂,我就用get_dummies!
  • 公平,我不太熟悉使用它,希望有更多知识的人回答!
【解决方案2】:

您可以通过连接所有现有列来创建一个单独的列并在其上应用CountVectorizer。请参考下面的示例代码:

import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer

shopping_list = [
    ["Apple", "Bread", "Fridge"],
    ["Rice", "Bread", "Milk"],
    ["Apple", "Rice", "Bread"],
    ["Rice", "Milk", "Milk"],
    ["Red Chillies", "Bread", "Milk"],
]

df = pd.DataFrame(shopping_list)
df.columns = ['col1', 'col2', 'col3']
vocab = set(df.values.flatten())
v = [i.lower() for i in vocab]
df['new'] = df.apply(' '.join, axis=1)

所以你的新数据框看起来像这样

    col1           col2     col3    new
0   Apple          Bread    Fridge  Apple Bread Fridge
1   Rice           Bread    Milk    Rice Bread Milk
2   Apple          Rice     Bread   Apple Rice Bread
3   Rice           Milk     Milk    Rice Milk Milk
4   Red Chillies   Bread    Milk    Red Chillies Bread Milk

现在您可以在新列上应用CountVectorizer,如下所示:

CV = CountVectorizer(vocabulary=vocab, , ngram_range=(1,5))
cv_matrix=CV.fit_transform(df.new)

您可以使用以下方法获取所需的数据框:

pd.DataFrame(cv_matrix.toarray(), columns= CV.get_feature_names())

    bread   milk    fridge  rice    apple   red chillies
0   1       0       1       0       1       0
1   1       1       0       1       0       0
2   1       0       0       1       1       0
3   0       2       0       1       0       0
4   1       1       0       0       0       1

希望这会有所帮助!

【讨论】:

  • 如果我有“红辣椒”,而不是“Apple”,这些词不会放在报告数据框中:(
  • 在这种情况下,您可以从您拥有的单词列表中创建自己的词汇表并将其传递给CountVectorizer,同时确保当您指定ngram_range 时它的最大值大于你能想到的最长的单词,这里我设置为 5。
【解决方案3】:

如果您发现创建一个将所有单独列组合在一起的新列作为开销,您可以使用生成器,它可以让您适应大型数据。

另外,在 pandas 数据框中读取稀疏矩阵的推荐方法是sparse.from_spmatrix。阅读更多here


cv = CountVectorizer()
pd.DataFrame.sparse.from_spmatrix(cv.fit_transform(
    ' '.join(x) for x in shopping_list),
    columns=cv.get_feature_names())

如果你需要在Dataframe中应用CountVectorizer,那么使用

' '.join(x[1:]) for x in df.itertuples()

【讨论】:

  • .iterrows() 有一些非常重要的缺点,我建议改用.itertuples()
  • 感谢您的建议。我会合并它。
猜你喜欢
  • 2010-10-29
  • 1970-01-01
  • 2014-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-24
相关资源
最近更新 更多