微忘録

好奇心に記憶力がついていかない人のブログ

2015年度版NLP100本ノック第2章をPython3で解く

前回(2015年度版NLP100本ノック第1章をPython3で解く - 微忘録)の続き。 bashとPython3で。各コードの実行結果は、こちらのリポジトリにて公開しています。

第2章: UNIXコマンドの基礎

hightemp.txtは,日本の最高気温の記録を「都道府県」「地点」「℃」「日」のタブ区切り形式で格納したファイルである.以下の処理を行うプログラムを作成し,hightemp.txtを入力ファイルとして実行せよ.さらに,同様の処理をUNIXコマンドでも実行し,プログラムの実行結果を確認せよ.

10. 行数のカウント

行数をカウントせよ.確認にはwcコマンドを用いよ.

%%bash
wc -l ./datasets/hightemp.txt
with open("./datasets/hightemp.txt","r") as hightemp:
    print(len(hightemp.readlines()))

11. タブをスペースに置換

タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.

%%bash
sed -e "s/\t/| /g" ./datasets/hightemp.txt
import re
with open("./datasets/hightemp.txt","r") as hightemp:
    lines = hightemp.readlines()
    print(lines,'\n')
    
    print([re.sub(r'\t'," ",hightemp)for hightemp in lines])

12. 1列目をcol1.txtに,2列目をcol2.txtに保存

各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.

%%bash
cut -f 1 ./datasets/hightemp.txt > ./datasets/col1.txt
cut -f 2 ./datasets/hightemp.txt > ./datasets/col2.txt
with open("./datasets/hightemp.txt") as hightemp:
    lines = hightemp.readlines()
    
    #col1.txt
    col1 = []
    for line in lines:
        col1.append(line.split()[0] + "\n") #"\n"で単語ごとに改行
        
    with open("./datasets/col1py.txt" , "w") as split:
            split.writelines(col1)
    
    #col2.txt
    col2 = []
    for line in lines:
        col2.append(line.split()[1] + "\n")
        
    with open("./datasets/col2py.txt" , "w") as split:
            split.writelines(col2)
            
    hightemp.close()

13. col1.txtとcol2.txtをマージ

12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ

%%bash
paste -d"\t" ./datasets/col1.txt ./datasets/col2.txt
with open("./datasets/col1.txt") as col1_file, open("./datasets/col2.txt") as col2_file:
    col1, col2 = col1_file.readlines(), col2_file.readlines()

with open("./datasets/merged.txt", "w") as writer:
    for a, b in zip(col1, col2):
        writer.write("\t".join([a.rstrip(),b]))
        
for i in open("./datasets/merged.txt"):
    print(i)

14. 先頭からN行を出力

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ.

%%bash
head -n 5 ./datasets/hightemp.txt
def head(n,file):
    with open(file,'r') as hightemp:
        lines = hightemp.readlines()
        for lineNumber in range(n):
            print(lines[lineNumber])
            
head(5, "./datasets/hightemp.txt")

15. 末尾のN行を出力

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ

%%bash
tail -n 5 ./datasets/hightemp.txt
def tail(n,file):
    with open(file,'r') as hightemp:
        lines = hightemp.readlines()
        stopline = len(lines) - n
        for lineNumber in range(stopline,len(lines),1):
            print(lines[lineNumber])
            
tail(5, "./datasets/hightemp.txt")

16. ファイルをN分割する

自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ.

%%bash
split -l 5 ./datasets/hightemp.txt ./datasets/n-split_
def splitfunc(file,n):
    with open(file) as filed:
        lines = filed.readlines()
    
    for i in range(n):
        with open("./datasets/splitblock%s.txt" % str(i), "w") as split:
            split.writelines(lines[n*i : n*(i +1)])
            
splitfunc("./datasets/hightemp.txt",3)

with open("./datasets/splitblock2.txt","r") as check:
    print(check.readlines())

17. 1列目の文字列の異なり

1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはsort, uniqコマンドを用いよ.

%%bash
cut -f 1 ./datasets/hightemp.txt |sort | uniq
with open("./datasets/hightemp.txt","r") as hightemp:
    lines = hightemp.readlines()
    
    col1 = []
    for line in lines:
        col1.append(line.split()[0] + "\n") #"\n"で単語ごとに改行

    li = set(col1)
    print(sorted(li))

18. 各行を3コラム目の数値の降順にソート

各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).

%%bash
sort -nk3r ./datasets/hightemp.txt
with open("./datasets/hightemp.txt", 'r') as hightemp:
    lines = hightemp.readlines()
    for line in sorted(lines,key=lambda x: x.split()[2], reverse=False):
        print(line)

19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる

各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.

%%bash
cut -f 1 ./datasets/hightemp.txt | sort |uniq -c | sort -r
from collections import Counter

with open("./datasets/hightemp.txt","r") as hightemp:
    lines = hightemp.readlines()
    
    li = []
    for line in lines:
        li.append(line.split()[0])
    
    counted = Counter(li)
    print(counted)