Манипулировать Pandas DataFrame, содержащим словари из Twitter API

Я работаю над сценарием, который использует API Twitter для извлечения последних статусов из списка пользователей. Я могу получить данные с помощью API, однако после преобразования их в DataFrame я получаю столбцы, в которых хранятся словари. Я хочу распространить индексы этих словарей на дополнительные столбцы. В конечном итоге я пытаюсь сохранить всю эту информацию в CSV.

Вот код:

import twython
import time
import pandas as pd
import numpy as np

app_key = ''
app_secret = ''
oauth_token = ''
oauth_token_secret = ''

twitter = twython.Twython(app_key, app_secret, oauth_token, oauth_token_secret)

screen_names = ['@', '@'] #enter screen names of interest

tweets = []

for screen_name in screen_names:
    tweets.extend(twitter.get_user_timeline(screen_name=screen_name, count=200))
    time.sleep(5)

df = pd.DataFrame(tweets)

который возвращает DataFrame (400,25). df[[2,3,5]] возвращает следующее:

     created_at                       entities                                         favorite_count
0    Thu Jun 19 13:14:39 +0000 2014  {u'symbols': [], u'user_mentions': [], u'hasht...       0
1    Thu Jun 19 11:53:51 +0000 2014  {u'symbols': [], u'user_mentions': [{u'id': 18...       0
2    Thu Jun 19 11:53:25 +0000 2014  {u'symbols': [], u'user_mentions': [], u'hasht...       3
3    Thu Jun 19 11:49:34 +0000 2014  {u'symbols': [], u'user_mentions': [], u'hasht...       0
4    Thu Jun 19 11:01:31 +0000 2014  {u'symbols': [], u'user_mentions': [{u'id': 18...       0

Как я могу разделить entities столбец через дополнительные столбцы? Например, я хотел бы symbols, user_mentions, hastags и т.д., чтобы стать дополнительными столбцами в df,

Любая помощь с благодарностью.

2 ответа

Решение

Я использую эту вспомогательную функцию для преобразования подсказки вложенных значений (вероятно, из API) в подсказку без вложенных значений.

def flatten(d):
    for key in d.keys():
        if isinstance(d[key], list):
            value = d.pop(key)
            for i, v in enumerate(value):
                d.update(flatten({'%s__%s' % (key, i): v}))
        elif isinstance(d[key], dict):
            value = d.pop(key)
            d.update([('%s__%s' % (key, sub), v) for (sub, v) in flatten(value).items()])
    return d

Вот пример того, что он делает:

In [2]: d = {'user': 'foo', 'data': {'choices': [0,1,2], 'type': 'x1'}}

In [3]: flatten(d)
Out[3]: 
{'data__choices__0': 0,
 'data__choices__1': 1,
 'data__choices__2': 2,
 'data__type': 'x1',
 'user': 'foo'}

В вашем примере вам нужно будет сделать:

df = pd.DataFrame([flatten(t) for t in tweets])

Следующее выполняет то, что я спросил в своем вопросе:

df_entities = pd.DataFrame(df['t_entities'].tolist())

df = df.join([df_entities, df_user])
Другие вопросы по тегам