代码之家  ›  专栏  ›  技术社区  ›  Foroand

熊猫数据帧中的词频计数耗时过长

  •  1
  • Foroand  · 技术社区  · 1 年前

    在这里研究了StackOverflow之后,我想出了下面的代码来计算数据帧的一列中单词的相对频率:

    df['objeto'] = df['objeto'].apply(unidecode.unidecode)
    df['objeto'] = df['objeto'].str.replace('[^\w\s]','')
    
    stop_words = nltk.corpus.stopwords.words('portuguese')
    stop_words.extend(['12', 'termo', 'aquisicao', 'vinte', 'demandas'])
    
    counter = Counter()
    
    for word in " ".join(df['objeto']).lower().split():
        if word not in stop_words:
            counter[word] += 1
    
    print(counter.most_common(10))
    
    for word, count in counter.most_common(100):
        print(word, count)
    

    问题是代码执行大约需要30秒。我做错了什么?有什么方法可以优化和改进我的代码吗?我打算创建一个这样的函数,以便在其他数据帧上执行此操作。

    我是熊猫的初学者,我很少使用它。我在这里做了一些关于stackoverflow的研究。非常感谢。

    1 回复  |  直到 1 年前
        1
  •  1
  •   jqurious FObersteiner    1 年前

    如果您提供某种可运行的示例,它会有所帮助:

    df = pd.DataFrame(dict(
       id = ['a', 'b', 'c', 'd'],
       objeto = ['Foo bar', 'hello Hi FOO', 'Yes hi Hello', 'Pythons PaNdas yeS']
    ))
    
    stop_words = ['foo', 'bar']
    

    这里的主要问题不是用熊猫来计数。

    熊猫有 .value_counts()

    在这种情况下,您希望将所有单词放在一列中,您可以使用 .explode()

    df['objeto'].str.casefold().str.split().explode()
    
    0        foo
    0        bar
    1      hello
    1         hi
    1        foo
    2        yes
    2         hi
    2      hello
    3    pythons
    3     pandas
    3        yes
    Name: objeto, dtype: object
    

    你可以 .mask() 删除以下单词 .isin(stop_words) 然后 .value_counts()

    df['objeto'].str.casefold().str.split().explode().mask(lambda word: word.isin(stop_words)).value_counts()
    
    objeto
    hello      2
    hi         2
    yes        2
    pythons    1
    pandas     1
    Name: count, dtype: int64