月別アーカイブ: 2019年4月

テキスト内のパラグラフ数と各パラグラフ内の文数を算出

表題の通り、あるコーパス内に収録されているテキストファイルのパラグラフ数と各パラグラフ内に含まれている文の数を算出する必要が生じたので、いつものようにpythonで処理スクリプトを書いてみた。
テキストファイルは、一文一行で収録されており、パラグラフは空白行で区別されている。したがって、テキストファイル内の空白行の数を数え、そこに1を足すことで、そのテキストファイルのパラグラフの数が算出できる。
たとえば、以下のようなテキストファイル(コーパスから部分抜粋)の場合は、空白行が2つなので、パラグラフの数は、3つとなる。

Today the trend of teaching English to small children is spreading in Japan.
Do you think whether it is good or not?
There are some merits and demerits in this point.
Begin with considering three merits of teaching English early.

First, it is often said that it is better to learning foreign language in early stage.
Children have a good ability to learn anything and the older they get, the less they can memorize things.
Regard with learning language, this is most prominent.
In addition that, English is easy language in the world.
So, it is good for children to learn English as early as they can.

Second, the needs of English has become more strong.
These days, a lot of foreigners have come to Japan and the chance for Japanese children to communicate with them is increasing.
If you meet a classmate who can only speak English and you want to make friends with him, you must speak English.

次に、各パラグラフに含まれている文の数を算出したい。
1パラグラフ目の文の数は、最初の空白行が何行目にあるか特定し(上の例の場合だと5行目)、そこから1を引けば1パラグラフ目に含まれている文の数が算出できる。
2パラグラフ目の文の数も同様に、2つ目の空白行から1つ目の空白行の差を出し、そこから1を引けば、2つ目のパラグラフの文の数が算出できる。上の例の場合だと、2つ目の空白行が11行目にあるので、11から5の差を出し、そこから1を引けば5という数字が得られので、2パラグラフ目の文の数は5ということになる。

というわけで、パラグラフの数と各パラグラフに含まれている文の数を算出するプログラムをpythonで書いてみた。パラグラフが一つしかないテキストの場合は、単に文の総数を記録して、パラグラフの数は1とした。

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys,re,glob,numpy as np

argvs = sys.argv
argc = len(argvs)

fw = open(sys.argv[2] + ".csv", 'w')
fw.write("Filename" + "," + "Sum of Sentences" + "," + "Sum of Paragraphs" + "," + "S in 1st" + ","+ "S in 2nd" + ","+ "S in 3rd" + ","+ "S in 4th" + ","+ "S in 5th" + ","+ "S in 6th" + ","+ "S in 7th" + ","+ "S in 8th" + "," + "S in 9th" + "," + "S in 10th" + "," + "S in 11th" + ","+ "S in 12th" + ","+ "S in 13th" + ","+ "S in 14th" + ","+ "S in 15th" + ","+ "S in 16th" + ","+ "S in 17th" + ","+ "S in 18th" + "," + "S in 19th" + "," + "S in 20th" + "\n")

for fn in sorted(glob.glob(sys.argv[1] + "*.txt")):
	filename = fn.split('/')[-1]
	with open(fn, 'r') as fn:
		files = fn.read()
		div = len(re.findall(r'^\n', files, flags = re.MULTILINE))
		if div != 0:
			regrep = re.sub('^\n', '%P\n', files, flags = re.MULTILINE).split("\n")
			numP = np.array([i for i, x in enumerate(regrep) if x == "%P"])
			numPS = [j for j in numP][0]
			numSEP = np.diff(numP) - 1
			L = [k for k in numSEP]
			L.insert(0, numPS)
			sumsens = sum(L)
			L.insert(0, div)
			result = ",".join(repr(l) for l in L)
			fw.write(filename + "," + str(sumsens) + "," + str(result) + "\n")
		else:
			sumsens2 = len([m.strip() for m in files.split("\n")])
			fw.write(filename + "," + str(sumsens2) + "," + str(1) + "," + str(sumsens2) + "\n")
fw.close()

もう少し短く簡潔に書けそうだが、ほしい数字を算出できたので良しとする。

引数は、対象フォルダ名と結果出力先(csv形式)の2つ。
出力形式は、ファイル名、総文数、総パラグラフ数、1パラ目の文数、2パラ目の文数、3パラ目の文数、、、という具合(見出しがちょっと雑。。だけどわかればいいのでとりあえず気にしないことにして、とりあえず20段落目までは見出しをつけた)。

出力例は、以下の通り。

Filename,Sum of Sentences,Sum of Paragraphs,S in 1st,S in 2nd,S in 3rd,S in 4th,S in 5th,S in 6th,S in 7th,S in 8th,S in 9th,S in 10th,S in 11th,S in 12th,S in 13th,S in 14th,S in 15th,S in 16th,S in 17th,S in 18th,S in 19th,S in 20th
JPN501.txt,25,4,9,5,3,8
JPN502.txt,29,5,7,10,6,0,6
JPN503.txt,8,2,4,4
JPN504.txt,23,4,8,4,7,4
JPN505.txt,19,2,13,6
JPN506.txt,18,4,1,3,6,8
JPN507.txt,24,4,1,10,4,9
JPN508.txt,16,4,1,7,4,4
JPN509.txt,18,5,1,4,3,4,6
JPN510.txt,1,1,1
JPN511.txt,25,8,1,4,5,3,3,1,4,4
JPN512.txt,22,4,1,4,8,9
JPN513.txt,30,8,1,1,10,4,1,3,6,4
JPN514.txt,6,2,1,5
JPN515.txt,22,5,1,4,8,4,5
JPN516.txt,18,4,1,3,8,6
JPN517.txt,29,7,1,3,7,6,4,4,4
JPN518.txt,24,5,1,7,5,7,4
JPN519.txt,27,4,1,8,9,9
JPN520.txt,19,4,1,4,8,6

こんな感じで、まぁ、ええか。
平成元年生まれなので、平成最後の日にブログを書こうと急いでプログラムを作成したので、結構雑になってしまったがひとまず思い取りに走ったので一安心。
令和でもマイペースにブログを更新していくことにしよう。。