【问题标题】:iterate over rows in pandas and count unique hashtags遍历 pandas 中的行并计算唯一的主题标签
【发布时间】:2019-05-01 00:46:09
【问题描述】:

我有一个包含数千条推文的 csv 文件。假设数据如下:

Tweet_id   hashtags_in_the_tweet

Tweet_1    [trump, clinton]
Tweet_2    [trump, sanders]
Tweet_3    [politics, news]
Tweet_4    [news, trump]
Tweet_5    [flower, day]
Tweet_6    [trump, impeach]

如您所见,数据包含 tweet_id 和每条推文中的主题标签。我想要做的是去所有的行,最后给我一些类似值的东西:

Hashtag    count
trump      4
news       2
clinton    1
sanders    1
politics   1
flower     1
obama      1
impeach    1

考虑到 csv 文件包含 100 万行(100 万条推文),最好的方法是什么?

【问题讨论】:

    标签: python pandas counter series unique-values


    【解决方案1】:

    Counter + chain

    Pandas 方法不适用于一系列列表。不存在矢量化方法。一种方法是使用标准库中的collections.Counter

    from collections import Counter
    from itertools import chain
    
    c = Counter(chain.from_iterable(df['hashtags_in_the_tweet'].values.tolist()))
    
    res = pd.DataFrame(c.most_common())\
            .set_axis(['Hashtag', 'count'], axis=1, inplace=False)
    
    print(res)
    
        Hashtag  count
    0     trump      4
    1      news      2
    2   clinton      1
    3   sanders      1
    4  politics      1
    5    flower      1
    6       day      1
    7   impeach      1
    

    设置

    df = pd.DataFrame({'Tweet_id': [f'Tweet_{i}' for i in range(1, 7)],
                       'hashtags_in_the_tweet': [['trump', 'clinton'], ['trump', 'sanders'], ['politics', 'news'],
                                                 ['news', 'trump'], ['flower', 'day'], ['trump', 'impeach']]})
    
    print(df)
    
      Tweet_id hashtags_in_the_tweet
    0  Tweet_1      [trump, clinton]
    1  Tweet_2      [trump, sanders]
    2  Tweet_3      [politics, news]
    3  Tweet_4         [news, trump]
    4  Tweet_5         [flower, day]
    5  Tweet_6      [trump, impeach]
    

    【讨论】:

    • 你的答案实际上计算了每个字母! hashtags_in_the_tweet 单元格是一个字符串,例如 '[trump, clinton]',你的方法给了我类似的东西: {'T' : 4, 'C' : 2 , ... }
    • @Arsalan,不,它没有。我没有编造答案中包含的输出。看起来你没有完全按照我的回答实现它。
    • 相信我,我正在计算每个字母的数量。当我将 csv 作为数据框读取时,如果我这样做: type(df['hashtags'][10]) ,结果是 str.和 df['hashtags'][10] 我得到 '[Mexico]'
    • 我需要从字符串中列出一个列表
    • @Arsalan,什么字符串?如果您不相信,请复制粘贴我添加的设置。
    【解决方案2】:

    听起来你想要collections.Counter 之类的东西,你可以这样使用...

    from collections import Counter
    from functools import reduce 
    import operator
    import pandas as pd 
    
    fold = lambda f, acc, xs: reduce(f, xs, acc)
    df = pd.DataFrame({'Tweet_id': ['Tweet_%s'%i for i in range(1, 7)],
                       'hashtags':[['t', 'c'], ['t', 's'], 
                                   ['p','n'], ['n', 't'], 
                                   ['f', 'd'], ['t', 'i', 'c']]})
    fold(operator.add, Counter(), [Counter(x) for x in df.hashtags.values])
    

    给你,

    Counter({'c': 2, 'd': 1, 'f': 1, 'i': 1, 'n': 2, 'p': 1, 's': 1, 't': 4})
    

    编辑:我认为 jpp 的答案会快很多。如果时间真的是一个限制,我会首先避免将数据读入DataFrame。我不知道原始的csv 文件是什么样的,但是逐行读取它作为文本文件,忽略第一个标记,然后将其余部分输入Counter 可能最终会快很多。

    【讨论】:

      【解决方案3】:

      np.hstack 的另一种选择并转换为pd.Series,然后使用value_counts

      import numpy as np
      
      df = pd.Series(np.hstack(df['hashtags_in_the_tweet'])).value_counts().to_frame('count')
      
      df = df.rename_axis('Hashtag').reset_index()
      
      print (df)
      
          Hashtag  count
      0     trump      4
      1      news      2
      2   sanders      1
      3   impeach      1
      4   clinton      1
      5    flower      1
      6  politics      1
      7       day      1
      

      【讨论】:

      • 一些推文不包含主题标签,并且 hastags_in_the_tweet 的字段是“[]”或什么都没有!所以我得到了错误:不能连接零维数组
      • @Arsalan 使用 df=df[df['hashtags_in_the_tweet'].astype(bool)] 首先过滤你的数据框
      • @Arsalan 你可以改用np.hstack
      • 你的答案实际上计算了每个字母! hashtags_in_the_tweet 单元格是一个字符串,例如 '[trump, clinton]',你的方法给了我类似的东西: {'T' : 4, 'C' : 2 , ... }
      • @Arsalan 它对我来说很好用。如果可能,请提供几行数据。把它上传到某个地方并给我链接。
      【解决方案4】:

      使用np.unique

      v,c=np.unique(np.concatenate(df.hashtags_in_the_tweet.values),return_counts=True)
      
      #pd.DataFrame({'Hashtag':v,'Count':c})
      

      即使问题看起来不同,但仍然是相关的unnesting问题

      unnesting(df,['hashtags_in_the_tweet'])['hashtags_in_the_tweet'].value_counts()
      

      【讨论】:

      • 一些推文不包含主题标签,并且 hastags_in_the_tweet 的字段是“[]”或 nan!所以我得到了错误:不能连接零维数组
      • @Arsalan 你看到我发表的评论了吗? df=df[df['hashtags_in_the_tweet'].astype(bool)].dropna()过滤后使用我的方法
      • 我应用了您的评论,它从数据中删除了所有行,随后使用您提出的答案,导致以下错误:ValueError:需要至少一个数组来连接
      • 你的答案实际上计算了每个字母! hashtags_in_the_tweet 单元格是一个字符串,例如 '[trump, clinton]',你的方法给了我类似的东西: {'T' : 4, 'C' : 2 , ... }
      【解决方案5】:

      所以上面的所有答案都有帮助,但实际上并没有用!我的数据的问题是:1)为某些推文提交的'hashtags' 的值是nan[]。 2)dataframe中'hashtags'字段的值为一串!上面的答案假设主题标签的值是主题标签列表,例如['trump', 'clinton'],虽然它实际上只是一个str'[trump, clinton]'。所以我在@jpp 的回答中添加了几行:

      #deleting rows with nan or '[]' values for in column hashtags 
      df = df[df.hashtags != '[]']
      df.dropna(subset=['hashtags'], inplace=True)
      
      #changing each hashtag from str to list
      df.hashtags = df.hashtags.str.strip('[')
      df.hashtags = df.hashtags.str.strip(']')
      df.hashtags = df.hashtags.str.split(', ')
      
      from collections import Counter
      from itertools import chain
      
      c = Counter(chain.from_iterable(df['hashtags'].values.tolist()))
      
      res = pd.DataFrame(c.most_common())\
              .set_axis(['Hashtag', 'count'], axis=1, inplace=False)
      
      print(res)
      

      【讨论】:

        猜你喜欢
        • 2018-11-07
        • 2020-04-05
        • 2019-03-20
        • 1970-01-01
        • 1970-01-01
        • 2023-01-16
        • 2021-02-01
        • 2016-09-14
        • 2021-10-30
        相关资源
        最近更新 更多