2017-08-28 1 views
0

JSONテキストファイルに保存されたツイートがあります。私はキーワードを含むつぶやきを望む友人がいて、ツイートは.csvに保存する必要があります。つぶやきを見つけるのは簡単ですが、私は2つの問題に遭遇し、良い解決策を見つけるのに苦労しています。ツイートを.csvとして保存します。文字列リテラルとエンティティが含まれます

サンプルデータはhereです。私は、動作していない.csvファイルと、各行がJSON形式のツイートであるファイルを含めました。

データフレームに入るために、私はpd.io.json.json_normalizeを使用します。それはスムーズに動作し、ネストされた辞書をうまく処理しますが、pd.to_csvは処理できません。なぜなら、文字列リテラルはよくわかります。一部のツイートにtextフィールドに'\n'が含まれており、そのときにpandasに新しい行が書き込まれます。

問題なし、pd['text']を処理して'\n'を削除します。結果ファイルにはまだ1388と比べて1863行が多すぎます。

tweets['text'] = [item.replace('\n', '') for item in tweets['text']] 
tweets['text'] = [item.replace('\r', '') for item in tweets['text']] 
tweets['text'] = [item.replace('\\', '') for item in tweets['text']] 
tweets['text'] = [item.replace('\'', '') for item in tweets['text']] 
tweets['text'] = [item.replace('\"', '') for item in tweets['text']] 
tweets['text'] = [item.replace('\a', '') for item in tweets['text']] 
tweets['text'] = [item.replace('\b', '') for item in tweets['text']] 
tweets['text'] = [item.replace('\f', '') for item in tweets['text']] 
tweets['text'] = [item.replace('\t', '') for item in tweets['text']] 
tweets['text'] = [item.replace('\v', '') for item in tweets['text']] 

同じ結果、pd.to_csvが実際のツイートよりも多くの行を持つファイルを保存します。私は、すべての文字列リテラルを置き換えるために、自分のコードを変更しました。私はすべての列で文字列リテラルを置き換えることができますが、それはclunkyです。

罰金、pandasを使用しないでください。 with open(outpath, 'w') as f:などは正しい行数の.csvファイルを作成します。ただし、pd.read_csvでファイルを読み取るか、1行ずつ読むことはできません。

Twitterがentitiesを処理する方法が原因で失敗します。ツイートのテキストにurl、言葉、ハッシュタグ、メディア、またはリンクが含まれている場合、Twitterはコンマを含む辞書を返します。 pandasがツイートを平らにすると、カンマは良い列で保存されます。しかし、データが読み込まれると、pandasは、1つの列を複数の列に分割する必要があります。たとえば、列は[{'screen_name': 'ProfOsinbajo','name': 'Prof Yemi Osinbajo','id': 2914442873,'id_str': '2914442873', 'indices': [0,' 13]}]'ように見えるかもしれませんので、カンマで分割は、あまりにも多くの列を作成:

[{'screen_name': 'ProfOsinbajo', 
'name': 'Prof Yemi Osinbajo', 
'id': 2914442873", 
'id_str': '2914442873'", 
'indices': [0, 
13]}] 

私もwith open(outpath) as f:を使用するかどうか結果です。そのアプローチでは、行を分割する必要があるので、コンマで区切ります。同じ問題 - リスト内にカンマがある場合、カンマで区切りたいとは思わない。

ファイルに保存したり、ファイルから読み込んだときに、これらのデータを1つの列として扱いたいとします。私は何が欠けていますか?the repository aboveのデータに関しては、forstackoverflow2.txtをツイートと同数の行を含む.csvに変換したいと考えています。このファイルをA.csvとし、それに100列あるとします。開いたときには、A.csvにも100列が必要です。

私が残した詳細があると確信していますので、お知らせください。

答えて

0

csvモジュールの使用。ファイルを行数をカウントしながら.csvとして書き出し、再度読み込み、再度カウントします。

結果が一致し、Excelで.csvを開くと、191列と1338行のデータが得られます。

import json 
import csv 

with open('forstackoverflow2.txt') as f,\ 
    open('out.csv','w',encoding='utf-8-sig',newline='') as out: 
    data = json.loads(next(f)) 
    print('columns',len(data)) 
    writer = csv.DictWriter(out,fieldnames=sorted(data)) 
    writer.writeheader() # write header 
    writer.writerow(data) # write the first line of data 
    for i,line in enumerate(f,2): # start line count at two 
     data = json.loads(line) 
     writer.writerow(data) 
    print('lines',i) 

with open('out.csv',encoding='utf-8-sig',newline='') as f: 
    r = csv.DictReader(f) 
    lines = list(r) 
    print('readback columns',len(lines[0])) 
    print('readback lines',len(lines)) 

出力:

columns 191 
lines 1338 
readback lines 1338 
readback columns 191 
0

@マークTolonenの答えは便利ですが、私は別のルートを行くことになりました。ツイートをファイルに保存するときに、JSONのどこからでも\r,\n\t\0の文字をすべて削除しました。次に、ファイルを保存してタブとして区切って、locationまたはtextのようなフィールドのカンマで、readの機能を混同しないようにします。

+0

csvモジュールはフィールドを引用符で囲み、フィールド内の引用符をエスケープします。したがって、カンマが引用符で囲まれたフィールドになるため、JSONの前処理やタブ区切りフィールドの使用は不要です。 –

+0

それは私が思ったことですが、自分のコードをうまく動作させることができなかった理由がわかりませんでした。多分それはそれをしたリテラル文字列を動かしていたでしょう。また、私は '' csv'''を試しませんでした。私はPythonを使用していない友人のためにこれをやっているので、私はその解決法を避けたいと思っていました。 – ZacharyST

関連する問題