перебирать строки в пандах и считать уникальные хэштеги - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть 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 содержит 1 миллион строк (1 миллион твитов), что такоелучший способ сделать это?

Ответы [ 5 ]

0 голосов
/ 29 ноября 2018

Так что все ответы выше были полезны, но на самом деле не работали!Проблема с моими данными: 1) значение 'hashtags' для некоторых твитов равно nan или [].2) Значение поля '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)
0 голосов
/ 29 ноября 2018

Использование 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()
0 голосов
/ 29 ноября 2018

Звучит так, будто вы хотите что-то вроде 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 может оказаться довольно быстрым.

0 голосов
/ 29 ноября 2018

Один вариант с 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
0 голосов
/ 29 ноября 2018

Counter + chain

Панды не предназначены для серий списков.Не существует векторизованного подхода.Одним из способов является использование 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]
...