从MongoDB获取嵌套数据并将其导入Pandas数据框架

6

我正在将Twitter数据(推文+元数据)收集到MongoDB服务器中。现在我想进行一些统计分析。为了将数据从MongoDB获取到Pandas数据框架中,我使用了以下代码:

cursor = collection.find({},{'id': 1, 'text': 1})

tweet_fields = ['id', 'text']

result = pd.DataFrame(list(cursor), columns = tweet_fields)

我成功地将数据加载到 Pandas 中,这太好了。现在我想对创建推文的用户进行一些分析,这也是我收集的数据。这些数据位于 JSON 的嵌套部分中(我不确定这是否是真正的 JSON),例如 user.id,它是 Twitter 用户帐户的 ID。

我只需使用点符号将其添加到游标中:

cursor = collection.find({},{'id': 1, 'text': 1, 'user.id': 1})

但是这会导致该列的值为 NaN。我发现问题出在数据结构上:

没有包含 user.id 的游标位。

[{'_id': ObjectId('561547ae5371c0637f57769e'),
  'id': 651795711403683840,
  'text': 'Video: Zuuuu gut! Caro Korneli besucht für extra 3 Pegida Via KFMW http://t.co/BJX5GKrp7s'},
 {'_id': ObjectId('561547bf5371c0637f5776ac'),
  'id': 651795781557583872,
  'text': 'Iets voor werkloze xenofobe PVV-ers, (en dat zijn waarschijnlijk wel de meeste).........Ze zoeken bij Frontex een paar honderd grenswachten.'},
 {'_id': ObjectId('561547ab5371c0637f57769c'),
  'id': 651795699881889792,
  'text': 'RT @ansichtssache47: Geht gefälligst arbeiten, die #Flüchtlinge haben Hunger! http://t.co/QxUYfFjZB5 #grenzendicht #rente #ZivilerUngehorsa…'}]

使用user.id位的光标位。

[{'_id': ObjectId('561547ae5371c0637f57769e'),
  'id': 651795711403683840,
  'text': 'Video: Zuuuu gut! Caro Korneli besucht für extra 3 Pegida Via KFMW http://t.co/BJX5GKrp7s',
  'user': {'id': 223528499}},
 {'_id': ObjectId('561547bf5371c0637f5776ac'),
  'id': 651795781557583872,
  'text': 'Iets voor werkloze xenofobe PVV-ers, (en dat zijn waarschijnlijk wel de meeste).........Ze zoeken bij Frontex een paar honderd grenswachten.',
  'user': {'id': 3544739837}}]

简而言之,我不明白如何将收集的数据中的嵌套部分放入Pandas数据框的单独列中。

2个回答

11

我使用类似于以下的函数将嵌套JSON行转换成Dataframe。函数使用了方便的 pandas json.normalize 函数:

import pandas as pd
from bson import json_util, ObjectId
from pandas.io.json import json_normalize
import json

def mongo_to_dataframe(mongo_data):

        sanitized = json.loads(json_util.dumps(mongo_data))
        normalized = json_normalize(sanitized)
        df = pd.DataFrame(normalized)

        return df

通过将mongo数据作为参数调用函数来传递。

sanitized = json.loads(json_util.dumps(mongo_data)) 将JSON行加载为常规JSON

normalized = json_normalize(sanitized) 展开数据

df = pd.DataFrame(normalized) 简单地将其转换为数据框


1
按照这个解决方案,我需要将存储在MongoDB中的所有数据加载到数据框中,对吗?考虑到我已经拥有的数据量,这似乎不是我想要做的事情。如果我使用您提出的方法,我是否需要使用Mongo导出为JSON函数作为“mongo_data”的输入? - Lam
1
是的,我使用这个函数的方式通常只查询我需要的数据并将所有数据加载到数据框中。我不确定我是否理解你问题的第二部分,但假设你所有的mongo数据都存储在变量x中。 clean_df = mongo_to_dataframe(x)将为您提供一个未嵌套的mongo数据的数据帧(dataframe)在clean_df中。 - metersk
1
你说你只查询需要加载到数据框中的数据。你的意思是我应该像下面这样使用它吗:sanitized = json.loads(json_util.dumps(collection.find({},{"id": 1, "text": 1, "user.id": 1}))) 编辑:这个方法很好用!而且文本解析比以前更好了! - Lam
1
上帝保佑你!! - iMajna

0
使用PyMongoArrow。这是MongoDB专门为此目的构建的工具。它允许您高效地将数据从MongoDB移入和移出其他数据格式,如pandas DataFrame、NumPy Array和Apache Arrow Table。
它还支持嵌套数据,并在从一个数据格式移动数据到另一个数据格式时,可选择定义数据的模式和数据类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接