我已经通过 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 数据示例。如果不允许,我会删除它...