【问题标题】:Count distinct words from a Pandas Data Frame从 Pandas 数据框中计算不同的单词
【发布时间】:2013-09-27 00:48:09
【问题描述】:

我有一个 Pandas 数据框,其中一列包含文本。我想获取出现在整个列中的唯一单词列表(空格是唯一的拆分)。

import pandas as pd

r1=['My nickname is ft.jgt','Someone is going to my place']

df=pd.DataFrame(r1,columns=['text'])

输出应如下所示:

['my','nickname','is','ft.jgt','someone','going','to','place']

计数也没有什么坏处,但这不是必需的。

【问题讨论】:

    标签: python text pandas


    【解决方案1】:

    使用set 创建唯一元素序列。

    df 进行一些清理以获取小写字符串并拆分:

    df['text'].str.lower().str.split()
    Out[43]: 
    0             [my, nickname, is, ft.jgt]
    1    [someone, is, going, to, my, place]
    

    此列中的每个列表都可以传递给set.update 函数以获取唯一值。使用apply 这样做:

    results = set()
    df['text'].str.lower().str.split().apply(results.update)
    print(results)
    
    set(['someone', 'ft.jgt', 'my', 'is', 'to', 'going', 'place', 'nickname'])
    

    或与来自 cmets 的 Counter() 一起使用:

    from collections import Counter
    results = Counter()
    df['text'].str.lower().str.split().apply(results.update)
    print(results)
    

    【讨论】:

    • 这是一个很好的解决方案。如果你想继续计数,你可以使用results = Counter()
    • 这太美了!
    • Counter 的解决方案很棒! :)
    • 很棒的解决方案,比其他解决方案扩展性更好
    • 这会占用大量内存。像这样翻转它以使用更少的 RAM:df['text'].apply(lambda x: results.update(x.split()))
    【解决方案2】:

    除了讨论之外,以下是在 92816 行数据帧上提出的三个解决方案(跳过转换为列表)的时间安排:

    from collections import Counter
    results = set()
    
    %timeit -n 10 set(" ".join(df['description'].values.tolist()).lower().split(" "))
    

    每个循环 323 毫秒 ± 4.46 毫秒(平均值 ± 标准偏差,7 次运行,每次 10 次循环)

    %timeit -n 10 df['description'].str.lower().str.split(" ").apply(results.update)
    

    每个循环 316 毫秒 ± 4.22 毫秒(7 次运行的平均值 ± 标准偏差,每次 10 次循环)

    %timeit -n 10 Counter(" ".join(df['description'].str.lower().values.tolist()).split(" "))
    

    每个循环 365 毫秒 ± 2.5 毫秒(7 次运行的平均值 ± 标准偏差,每次 10 次循环)

    len(list(set(" ".join(df['description'].values.tolist()).lower().split(" "))))
    

    13561

    len(results)
    

    13561

    len(Counter(" ".join(df['description'].str.lower().values.tolist()).split(" ")).items())
    

    13561

    我也尝试了仅使用 Pandas 的方法,但它花费了更长的时间,并且使用了 > 25GB 的 RAM 来交换我的 32GB 笔记本电脑。

    所有其他人都非常快。我会使用解决方案 1 作为单行,如果需要字数统计,我会使用 3。

    【讨论】:

      【解决方案3】:

      TL;DR

      使用collections.Counter 获取数据框中列中唯一单词的计数(不包含停用词)

      给定:

      $ cat test.csv 
      Description
      crazy mind california medical service data base...
      california licensed producer recreational & medic...
      silicon valley data clients live beyond status...
      mycrazynotes inc. announces $144.6 million expans...
      leading provider sustainable energy company prod ...
      livefreecompany founded 2005, listed new york stock...
      

      代码:

      from collections import Counter
      from string import punctuation
      
      import pandas as pd
      
      from nltk.corpus import stopwords
      from nltk import word_tokenize
      
      stoplist = set(stopwords.words('english') + list(punctuation))
      
      df = pd.read_csv("test.csv", sep='\t')
      
      texts = df['Description'].str.lower()
      
      word_counts = Counter(word_tokenize('\n'.join(texts)))
      
      word_count.most_common()
      

      [出]:

      [('...', 6), ('california', 2), ('data', 2), ('crazy', 1), ('mind', 1), ('medical', 1), ('service', 1), ('base', 1), ('licensed', 1), ('producer', 1), ('recreational', 1), ('&', 1), ('medic', 1), ('silicon', 1), ('valley', 1), ('clients', 1), ('live', 1), ('beyond', 1), ('status', 1), ('mycrazynotes', 1), ('inc.', 1), ('announces', 1), ('$', 1), ('144.6', 1), ('million', 1), ('expans', 1), ('leading', 1), ('provider', 1), ('sustainable', 1), ('energy', 1), ('company', 1), ('prod', 1), ('livefreecompany', 1), ('founded', 1), ('2005', 1), (',', 1), ('listed', 1), ('new', 1), ('york', 1), ('stock', 1)]
      

      【讨论】:

        【解决方案4】:

        如果 Dataframe 有“a”、“b”、“c”等列,并计算每列的不同单词,那么 你可以使用,

        Counter(dataframe['a']).items()
        

        【讨论】:

        • 这会计算列中整个短语的出现次数,而不是单个单词。
        【解决方案5】:

        如果你想从 DataFrame 构造中做到这一点:

        import pandas as pd
        
        r1=['My nickname is ft.jgt','Someone is going to my place']
        
        df=pd.DataFrame(r1,columns=['text'])
        
        df.text.apply(lambda x: pd.value_counts(x.split(" "))).sum(axis = 0)
        
        My          1
        Someone     1
        ft.jgt      1
        going       1
        is          2
        my          1
        nickname    1
        place       1
        to          1
        dtype: float64
        

        如果您想要更灵活的标记化,请使用 nltk 及其 tokenize

        【讨论】:

        • 感谢解决问题的整个问题:DataFramecount
        • 我的数据帧真的很慢(n = 90,000)
        【解决方案6】:

        以 @Ofir Israel 的回答为基础,专门针对 Pandas:

        from collections import Counter
        result = Counter(" ".join(df['text'].values.tolist()).split(" ")).items()
        result
        

        会给你你想要的,这会将文本列系列值转换为列表,按空格分割并计算实例。

        【讨论】:

          【解决方案7】:

          使用collections.Counter:

          >>> from collections import Counter
          >>> r1=['My nickname is ft.jgt','Someone is going to my place']
          >>> Counter(" ".join(r1).split(" ")).items()
          [('Someone', 1), ('ft.jgt', 1), ('My', 1), ('is', 2), ('to', 1), ('going', 1), ('place', 1), ('my', 1), ('nickname', 1)]
          

          【讨论】:

            【解决方案8】:
            uniqueWords = list(set(" ".join(r1).lower().split(" ")))
            count = len(uniqueWords)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-11-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-08-12
              • 1970-01-01
              相关资源
              最近更新 更多