Обработка большого количества твитов для исследовательского анализа данных, таких как количество уникальных твитов и гистограмма количества твитов на пользователя - PullRequest
1 голос
/ 19 июня 2020

У меня есть 14 миллионов твитов, которые находятся в одном файле tweet.txt (предоставленном мне), в котором весь JSON твит - это одна строка текстового файла. Я хочу получить базовую c статистику, такую ​​как количество уникальных твитов, количество уникальных пользователей и историограмму количества ретвитов для каждого твита, а также гистограмму твитов для каждого пользователя. Позже меня интересует, возможно, более сложный анализ.

У меня есть следующий код, но он очень медленный. Я оставил его работать на весь день, и обработано только 200 000 твитов. Можно ли как-то исправить текущий код, чтобы его можно было ускорить? Является ли нынешняя идея создания кадра данных pandas из 14 миллионов твитов хорошей идеей или осуществимой для исследовательского анализа данных? Моя текущая машина имеет 32 ГБ оперативной памяти и 12 процессоров. Если это невозможно на этой машине, у меня также есть доступ к общему кластеру в моем университете.

import pandas as pd

import json
from pprint import pprint
tweets = open('tweets.txt')

columns = ['coordinates', 'created_at', 'favorite_count', 'favorited', 'tweet_id', 'lang', 'quote_count', 'reply_count', 'retweet_count',
           'retweeted', 'text', 'timestamp_ms', 'user_id', 'user_description', 'user_followers_count', 'user_favorite_count',
           'user_following_count', 'user_friends_count', 'user_location', 'user_screenname', 'user_statuscount', 'user_profile_image', 'user_name', 'user_verified' ]

#columns =['coordinates', 'created_at']


df = pd.DataFrame()

count = 0
for line in tweets:
    count += 1
    print(count)
    #print(line)
    #print(type(line))
    tweet_obj = json.loads(line)
    #pprint(tweet_obj)
    #print(tweet_obj['id'])
    #print(tweet_obj['user']['id'])
    df = df.append({'coordinates': tweet_obj['coordinates'],
                    'created_at': tweet_obj['created_at'],
                    'favorite_count': tweet_obj['favorite_count'],
                    'favorited': tweet_obj['favorited'],
                    'tweet_id': tweet_obj['id'],
                    'lang': tweet_obj['lang'],
                    'quote_count': tweet_obj['quote_count'],
                    'reply_count': tweet_obj['reply_count'],
                    'retweet_count': tweet_obj['retweet_count'],
                    'retweeted': tweet_obj['retweeted'],
                    'text': tweet_obj['text'],
                    'timestamp_ms': tweet_obj['timestamp_ms'],
                    'user_id': tweet_obj['user']['id'],
                    'user_description': tweet_obj['user']['description'],
                    'user_followers_count': tweet_obj['user']['followers_count'],
                    'user_favorite_count': tweet_obj['user']['favourites_count'],
                    'user_following': tweet_obj['user']['following'],
                    'user_friends_count': tweet_obj['user']['friends_count'],
                    'user_location': tweet_obj['user']['location'],
                    'user_screen_name': tweet_obj['user']['screen_name'],
                    'user_statuscount': tweet_obj['user']['statuses_count'],
                    'user_profile_image': tweet_obj['user']['profile_image_url'],
                    'user_name': tweet_obj['user']['name'],
                    'user_verified': tweet_obj['user']['verified']

                    }, ignore_index=True)

df.to_csv('tweets.csv')

1 Ответ

1 голос
/ 19 июня 2020

Одним значительным увеличением скорости будет преобразование append словаря в list без использования df.append, а затем за пределами l oop создание фрейма данных. Что-то вроде:

count = 0
l_tweets = []
for line in tweets:
    count += 1
    tweet_obj = json.loads(line)
    #append to a list
    l_tweets.append({'coordinates': tweet_obj['coordinates'],
                     # ... copy same as yours
                     'user_verified': tweet_obj['user']['verified']
                    })
df = pd.DataFrame(l_tweets, columns=columns)

Что касается того, может ли ваша RAM обрабатывать 14 миллионов твитов, я действительно не знаю. В кластере обычно да, но я думаю, что то, как обрабатывать данные, зависит от конфигурации кластера.

Или, может быть, если вы убедитесь, что порядок элементов такой же, как в вашем списке columns, тогда также будет работать list вместо словаря:

count = 0
l_tweets = []
for line in tweets:
    count += 1
    tweet_obj = json.loads(line)
    #append to a list
    l_tweets.append([tweet_obj['coordinates'], tweet_obj['created_at'], 
                     # ... copy just the values here in the right order
                     tweet_obj['user']['name'], tweet_obj['user']['verified']
                    ])
df = pd.DataFrame(l_tweets, columns=columns)
...