ツイートを収集するために AWS 経由でパブリック ストリームをセットアップしましたが、予備的な分析を行いたいと考えています。すべてのデータは S3 バケット (5 MB のファイル) に保存されました。
すべてをダウンロードし、すべてのファイルを 1 つにマージしました。各ツイートは、Twitter の仕様に従って標準の JSON オブジェクトとして保存されます。
基本的に、統合ファイルには複数の JSON オブジェクトが含まれます。Python に読み込まれるときに辞書のリストのように見えるように、左角括弧と右角括弧 ( [] ) を追加しました。したがって、構造は次のようになります (ここに Twitter データを投稿できるかどうかはわかりません)。
[{"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.
なぜこれが起こっているのかはわかりませんが、ファイル全体を一度にメモリにロードしようとしていることが原因であると予想されます。これは正しいです?
だから、明らかにjsonファイルを解析できるijsonを使用しようとしていました。次のコードを書いてみました。
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 形式であることがわかりました。したがって、今のところ、その 1 つのファイルを除外しました。
基本的に、上記の形式 ([{json1}, {json2}]) のデータセットがあります。ここで、{} 内の各エンティティはツイートを表します。
これが有効な JSON であることを確認したので、私の目標は、各 JSON を辞書として表現して Python に組み込むことでした (これらのファイルを簡単に操作できるようにするため)。非効率な場合、誰かがここで私の思考プロセスを修正できますか?
そのために、次のことを行いました。
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
問題は、 「str」には属性「get」がないと言い続けているため、 current_tweet.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 データのサンプルです。これが許可されていない場合は、削除します...