2

我已经通过 AWS 建立了一个公共流来收集推文,现在想做一些初步分析。我的所有数据都存储在 S3 存储桶中(在 5mb 文件中)。

我下载了所有内容并将所有文件合并为一个。根据 Twitter 规范,每条推文都存储为标准 JSON 对象。

基本上,合并文件包含多个 JSON 对象。我添加了左方括号和右方括号 ( [] ) 以使它看起来像一个字典列表,以便在将其读入 Python 时使用。所以结构有点像这样(我不确定我是否可以在这里发布推特数据):

[{"created_at":"Mon Sep 19 23:58:50 +000 2016", "id":<num>, "id_str":"<num>","text":"<tweet message>", etc.}, 
{same as above},
{same as above}]

删除第一条推文后,我将所有内容放入 www.jsonlint.com 并确认它是有效的 JSON 数据结构。

现在,我正在尝试将这些数据加载到 Python 中,并希望对推文中的不同术语进行一些基本计数(例如,@HillaryClinton 在推文文本中提到了多少次等)。

以前使用较小的数据集,我能够摆脱这样的代码:

import json
import csv
import io
data_json = open('fulldata.txt', 'r', encoding='utf-8')
data_python = json.load(data.json)

然后,我将各个字段的数据写入 CSV 文件,并以这种方式进行分析。这适用于 2GB 文件。

现在我有一个 7GB 的文件,我注意到如果我使用这种方法,Python 会在“json.load(data.json)”行中抛出一个错误,说“OSError: [Errno 22] Invalid Argument.

我不确定为什么会发生这种情况,但我预计这可能是因为它试图一次将整个文件加载到内存中。这个对吗?

所以我试图使用 ijson ,它显然可以让你解析 json 文件。我尝试编写以下代码:

import ijson
f = open('fulldata.txt', 'r', encoding='utf-8')
content = ijson.items(f, 'item')
for item in content:
    <do stuff here>

使用这个实现,我在“for item in content”这一行得到一个错误,说“ijson.backends.python.unexpectedsymbol:unexpected symbol '/u201c' at 1

我还尝试浏览数据文件的每一行,并将其作为 JSON 行格式浏览。因此,假设每一行都是一个 JSON 对象,我写道:

raw_tweets = []
with open('full_data.txt', 'r', encoding='utf-8') as full_file:
     for line in full_file:
         raw_tweets.append(json.dumps(line))
print(len(raw_tweets)) #this worked. got like 2 million something as expected!
enter code here

但是在这里,列表中的每个条目都是一个字符串而不是字典,这使得我很难从中解析出我需要的数据。有没有办法修改最后一个代码以使其按我的需要工作?但即便如此,考虑到内存限制,将整个数据集加载到列表中是否仍会使未来的分析变得困难?

我对继续进行此操作的最佳方法有些困惑。我真的很想在 Python 中做到这一点,因为我正在尝试学习如何使用 Python 工具进行此类分析。

有没有人有这方面的经验?我真的很愚蠢还是误解了一些非常基本的东西?

编辑:

所以,我首先去了 www.jsonlint.com 并粘贴了我的整个数据集,发现在删除第一条推文后,它是有效的 JSON 格式。所以现在我只是排除了那个文件。

我基本上有一个上述格式的数据集 ([{json1}, {json2}] 其中 {} 中的每个实体都代表一条推文。

现在我确认它是一个有效的 JSON,我的目标是将它放入 python 中,每个 JSON 都表示为一个字典(这样我就可以轻松地操作这些文件)。如果效率低下,有人可以在这里纠正我的思维过程吗?

为此,我做了:

raw_tweets=[]
with open('fulldata.txt', 'r', encoding='ISO-8859-1') as full_file:
     for line in full_file:
         raw_tweets.append(json.dumps(line))
#This successfully wrote each line of my file into a list. Confirmed by checking length, as described previously.
#Now I want to write this out to a csv file. 
csv_out = io.open("parsed_data.csv", mode = 'w', encoding='ISO-8859-1')
fields = u'created_at,text,screen_name,followers<friends,rt,fav'
csv_out.write(fields) #Write the column headers out. 
csv_out.write(u'\n')
#Now, iterate through the list. Get each JSON object as a dictionary and pull out the relevant information.
for tweet in raw_tweets:
#Each "tweet" is {json#},\n'
    current_tweet = json.loads(tweet) #right now everything is a list of strings in the {} format but it's just a string and not a dictionary. If I convert it to a JSON object, I should be able to make a dictionary form of the data right?
row = [current_tweet.get('created_at'), '"' + line.get('text').replace('"','""') + '"', line.get('user).get('screen_name')] #and I continue this for all relevant headers

问题是,我说 current_tweet.get 的最后一行不起作用,因为它一直说“str”没有属性“get”,所以我不确定为什么 json.loads() 没有给我字典。 ..

编辑#2

一位用户建议我删除 [ 和 ] 以及结尾的逗号,以便每一行都有有效的 JSON。这样我就可以 json.loads() 每行。我按照建议删除了括号。对于逗号,我这样做了:

raw_tweets=[]
with open('fulldata.txt', 'r', encoding='ISO-8859-1') as full_file:
     for line in full_file:
         no_comma = line[:-2] #Printed this to confirm that final comma was removed
         raw_tweets.append(json.dumps(line))

这给出了一个错误提示 ValueError: Expecting ':' Delimiter: Line 1 Column 2305 (char 2304)

为了调试它,我打印了第一行(即我刚才说 print(no_comma)),我注意到 Python 打印的内容实际上有多个推文......当我在“UltraEdit”之类的编辑器中打开它时,我注意到每条推文是一条不同的行,所以我假设每个 JSON 对象都由换行符分隔。但是在这里,当我在逐行迭代后打印结果时,我看到它同时拉入了多条推文。

我应该以不同的方式迭代吗?我删除逗号的方法是否合适,还是应该单独预处理文件?

我很确定我的 JSON 格式很差,但我不确定为什么以及如何修复它。这是我的 JSON 数据示例。如果不允许,我会删除它...

https://ufile.io/47b1

4

2 回答 2

1

我是一个非常新的用户,但我可能能够提供部分解决方案。我相信您的格式已关闭。如果没有 JSON 格式,您不能只将其作为 JSON 导入。如果您可以将推文放入数据框(或单独的数据框),然后使用“DataFrame.to_json”命令,您应该能够解决此问题。如果尚未安装,您将需要 Pandas。

熊猫 - http://pandas.pydata.org/pandas-docs/stable/10min.html

数据框 - http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_json.html

于 2016-09-30T00:26:07.537 回答
0

对于大型数据集,不要将整个文件作为 JSON 对象,而是每行放置一个 JSON 对象!

要修复格式,您应该

  1. 删除[文件开头的
  2. 删除]文件末尾的
  3. 去掉每行末尾的逗号

然后你可以这样读取文件:

with open('one_json_per_line.txt', 'r') as infile:
    for line in infile:
        data_row = json.loads(line)

如果可能的话,我建议使用不同的存储。想到了 SQLite。

于 2016-09-30T06:22:37.890 回答