如何在Pandas DataFrame中访问嵌入的json对象?

时间:2013-09-06 19:32:54

标签: python json mongodb twitter pandas

TL; DR如果Pandas DataFrame中的加载字段本身包含JSON文档,那么它们如何在像时尚这样的Pandas中使用?

目前我直接将Twitter库(twython)中的json / dictionary结果转储到Mongo集合(此处称为用户)。

from twython import Twython
from pymongo import MongoClient

tw = Twython(...<auth>...)

# Using mongo as object storage 
client = MongoClient()
db = client.twitter
user_coll = db.users

user_batch = ... # collection of user ids
user_dict_batch = tw.lookup_user(user_id=user_batch)

for user_dict in user_dict_batch:
    if(user_coll.find_one({"id":user_dict['id']}) == None):
        user_coll.insert(user_dict)

填充此数据库后,我将文档读入Pandas:

# Pull straight from mongo to pandas
cursor = user_coll.find()
df = pandas.DataFrame(list(cursor))

这就像魔法一样:

Pandas is magic

我希望能够破坏“状态”字段Pandas样式(直接访问属性)。有办法吗?

status field

编辑:df ['status:text']之类的东西。状态包含“text”,“created_at”等字段。一个选项可能是像Jess McKinney正在研究的this pull request那样展平/规范这个json字段。

1 个答案:

答案 0 :(得分:21)

一种解决方案就是使用Series构造函数粉碎它:

In [1]: df = pd.DataFrame([[1, {'a': 2}], [2, {'a': 1, 'b': 3}]])

In [2]: df
Out[2]: 
   0                   1
0  1           {u'a': 2}
1  2  {u'a': 1, u'b': 3}

In [3]: df[1].apply(pd.Series)
Out[3]: 
   a   b
0  2 NaN
1  1   3

在某些情况下,您需要concat将此{{3}}替换为数据框来代替dict行:

In [4]: dict_col = df.pop(1)  # here 1 is the column name

In [5]: pd.concat([df, dict_col.apply(pd.Series)], axis=1)
Out[5]: 
   0  a   b
0  1  2 NaN
1  2  1   3

如果它变得更深,你可以这样做几次......