ディレクトリ構造を持つjsonファイルたちを形態素解析をしてcsvに一括変換
複雑なディレクトリ構造を持つjsonファイルをcsvに一括変換したい
日付毎に記録されたjsonデータをcsvに変換したいとする。
ここでまず以下の方法が考えられる1. json⇒csvに変換してくれるサイトを利用2. pythonの変換ライブラリ(pd.read_json()など)を使用する
しかしながら、このどちらも以下の問題を抱えていた
1...一度に変換できる容量に制限アリ&同様のディレクトリを手作業で作り直すのが面倒
2...pd.json_read()でエンコーディングエラー多発
そのため、今回はjson⇒numpy⇒csvとワンクッション置いて必要な情報のみを取り出した
1. 重for文をさけて2018-01-02.jsonのようなファイルパスを表現する
まずこのように内包表記を定義します
#内包表記で重複for分を避ける
years = range(2018,2019)
months = range(1, 13)
days = range(1,32)
combinations = [(year, month, day)
for year in years
for month in months
for day in days]
この内包表記を利用することで、for文は一度で表現することができます`
for year, month, day in combinations:
#ファイル名に合うようにゼロ埋めを実行. ex)2018-09-01
date = str(year) + '-' + str(month).zfill(2) + '-' + str(day).zfill(2)
#pathの生成を自動化(ディレクトリ名もそのうち自動で)
path = "C:/Users/名前/Desktop/json/目的のディレクトリ/" + str(date) + ".json"
2.ファイルパスの判定とjson⇒numpy
1でjsonファイルのpathを自動生成することが出来ました。しかしながら、生成した日付のjsonファイルがない場合エラーを吐いてしまいます。
そこで、os.path.isfile(path)という関数を使用することでpathの存在を判定し、同時にjson⇒numpyへ変換してしまいましょう
if(os.path.isfile(path)):
#日付代わりにカウンターを更新。これが行の値になる
count += 1
#以下、encodingを指定しないとエラーを吐く
f = None
f = open(path, 'r', encoding="utf-8")
#ファイルのデータを取得
json_data = json.load(f)
#numpyにぶち込む
data_ = []
data_ = np.array(json_data)
elseは今回特に指定しませんでした。
3.データのクリーニング(今回は自然言語処理用)と単語抽出
今回使用するjsonファイルの特徴を見てクリーニング方法を検討します
テキストを含むjsonファイルはすべて
{'type': 'message'
から始まっていたので、こちらを判定に利用しました
#data_をクリーニングしてから全体の配列に格納
for i in range(len(data_)):
data_text = str(data_[i])
text_ = data_text.split(',')
#メッセージだけを取り出す
if(text_[0]=="{'type': 'message'"):
rm = "'text': "
pure_text = clean_text(text_[2].replace(rm,''))
print(pure_text)
tokens = t.tokenize(pure_text)
for token in tokens:
partOfSpeech = token.part_of_speech.split(',')[0]
# 今回抽出するのは名詞だけ。(もちろん他の品詞を追加、変更、除外可能。)
if partOfSpeech == u'名詞':
each_data.append(token.surface) # token.surfaceは表層形(語彙)。詳しくはこちら...http://ailaby.com/janome/
#抽出した名詞たちをdata_allに追加していく。
data_all.append(each_data)
each_data = []
4. 形態要素解析後のデータをexcelファイルに出力
## 文章を形態素毎に分割したデータをいれるエクセルファイル作成(今回は名詞のみ)
# 例)C:\Users\〜\Documents\〜
# パスの前のrは省略しない
data_book = xlsxwriter.Workbook("例)C:\Users\〜\Documents\ファイル名1.xlsx")
# シート作成・変数定義
data_sheet = data_book.add_worksheet('data')
for row in range(len(data_all)):
for i in range(len(data_all[row])):
data_sheet.write(row, i, data_all[row][i])
# エクセルを保存
data_book.close()
5. 名詞の頻度ランキングをexcelファイルに出力
#すべての語彙を同じ配列に格納
chain_data = list(chain.from_iterable(data_all))
c = Counter(chain_data)
result_ranking = c.most_common(1000) # 出現頻度100位までを変数に格納
# 語彙出現ランキングを記述するエクセルを作成(パスはファイルを作成したいところに)
result_book = xlsxwriter.Workbook("例)C:\Users\〜\Documents\ファイル名2.xlsx")
# resultという名前のシートを作成
result_sheet = result_book.add_worksheet('result')
for row in range(len(result_ranking)):
for i in range(len(result_ranking[row])):
result_sheet.write(row, i, result_ranking[row][i])
# エクセルを保存
result_book.close()
6.おつかれさまでした
これで大体のjsonファイルをcsvで取り扱えそうですね
コード全文
#python:analysis.py
import pandas as pd
import json
import os
import os.path
import numpy as np
from janome.tokenizer import Tokenizer
import xlrd
import xlsxwriter
from collections import Counter
from itertools import chain
#テキストデータをクリーニングする関数
def clean_text(replaced_text):
"""
\S+ matches all non-whitespace characters (the end of the url)
:param html_text:
:return:
"""
replaced_text = re.sub(r'http\S+', '', replaced_text)
replaced_text = re.sub(r'[@@]\w+', '', replaced_text) # メンションの除去
replaced_text = re.sub(r' ', ' ', replaced_text) # 全角空白の除去
replaced_text = re.sub(r'<', ' ', replaced_text) # 全角空白の除去
replaced_text = re.sub(r'>', ' ', replaced_text) # 全角空白の除去
return replaced_text
########################################################
#メイン処理
if __name__ == "__main__":
#内包表記で重複for分を避ける
years = range(2018,2019)
months = range(1, 13)
days = range(1,32)
combinations = [(year, month, day)
for year in years
for month in months
for day in days]
#内包表記で繰り返し処理
#縦軸の日付をうまく行列に反映できないので、とりあえずカウンターを設置する
count = 0
data_all = [] #テキストファイルのまとめ先
each_data = [] #語彙の格納先
t = Tokenizer() #形態素解析用のモジュール
#1.形態素解析
for year, month, day in combinations:
#ファイル名に合うようにゼロ埋めを実行. ex)2018-09-01
date = str(year) + '-' + str(month).zfill(2) + '-' + str(day).zfill(2)
#pathの生成も自動化(channelもそのうち自動で)適宜読み替えてpathを設定してください
path = "C:/Users/ユーザー名/Desktop/json/目標のディレクトリ/" + str(date) + ".json"
if(os.path.isfile(path)):
#日付代わりにカウンターを更新。これが行の値になる
count += 1
#encodingを指定しないとエラーを吐く
f = None
f = open(path, 'r', encoding="utf-8")
#print(f)
#ファイルのデータを取得
json_data = json.load(f)
#numpyにぶち込む
data_ = []
data_ = np.array(json_data)
#count行目に入る値
print(count)
#data_をクリーニングしてから全体の配列に格納
for i in range(len(data_)):
#print(data_[i])
data_text = str(data_[i])
#print(data_text)
text_ = data_text.split(',')
#メッセージだけを取り出す
if(text_[0]=="{'type': 'message'"):
rm = "'text': "
pure_text = clean_text(text_[2].replace(rm,''))
print(pure_text)
tokens = t.tokenize(pure_text)
for token in tokens:
partOfSpeech = token.part_of_speech.split(',')[0]
# 今回抽出するのは名詞だけ。(もちろん他の品詞を追加、変更、除外可能。)
if partOfSpeech == u'名詞':
each_data.append(token.surface) # token.surfaceは表層形(語彙)。詳しくはこちら...http://ailaby.com/janome/
#抽出した名詞たちをdata_allに追加していく。
data_all.append(each_data)
each_data = []
###########################################################
## 文章を形態素毎に分割したデータをいれるエクセルファイル作成(今回は名詞のみ)
# 例)C:\Users\〜\Documents\〜
# パスの前のrは省略しない
data_book = xlsxwriter.Workbook("例)C:\Users\〜\Documents\ファイル名1.xlsx")
# シート作成・変数定義
data_sheet = data_book.add_worksheet('data')
for row in range(len(data_all)):
for i in range(len(data_all[row])):
data_sheet.write(row, i, data_all[row][i])
# エクセルを保存
data_book.close()
############################################################
#すべての語彙を同じ配列に格納
chain_data = list(chain.from_iterable(data_all))
c = Counter(chain_data)
result_ranking = c.most_common(1000) # 出現頻度100位までを変数に格納
# 語彙出現ランキングを記述するエクセルを作成(パスはファイルを作成したいところに)
result_book = xlsxwriter.Workbook("例)C:\Users\〜\Documents\ファイル名2.xlsx")
# resultという名前のシートを作成
result_sheet = result_book.add_worksheet('result')
for row in range(len(result_ranking)):
for i in range(len(result_ranking[row])):
result_sheet.write(row, i, result_ranking[row][i])
# エクセルを保存
result_book.close()
この記事が気に入ったらサポートをしてみませんか?