自然言語処理100本ノック2020やってみる【chap2】
はじめに
自然言語処理100本ノック2020のchapter2をやってみた記事です。
詳細は以下のchap1の記事を参照してください。
hirune-is-supremacy.hatenablog.com
第2章: UNIXコマンド
コード
使用データ
popular-names.txtは,アメリカで生まれた赤ちゃんの「名前」「性別」「人数」「年」をタブ区切り形式で格納したファイルである.
以下の処理を行うプログラムを作成し,popular-names.txtを入力ファイルとして実行せよ.
さらに,同様の処理をUNIXコマンドでも実行し,プログラムの実行結果を確認せよ.
!wget https://nlp100.github.io/data/popular-names.txt # Python用 txt_file = "popular-names.txt"
10. 行数のカウント
行数をカウントせよ.確認にはwcコマンドを用いよ.
python
with open(txt_file) as f: txt = f.readlines() print(len(txt))
2780
unix
!wc popular-names.txt
2780 11120 55026 popular-names.txt
11. タブをスペースに置換
タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.
python
with open(txt_file) as f: txt = f.readlines() new_txt = [] for i in txt: new_txt.append(i.replace("\t", " ").replace("\n", "")) print("\n".join(new_txt))
Mary F 7065 1880
Anna F 2604 1880
Emma F 2003 1880
Elizabeth F 1939 1880
Minnie F 1746 1880
...(以下略
unix
!sed -i "s/\t/ /g" popular-names.txt
12. 1列目をcol1.txtに,2列目をcol2.txtに保存
各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.
python
files = ["col1.txt", "col2.txt"] for num, file in enumerate(files): with open(txt_file) as f: txt = f.readlines() with open(file, "w") as w_f: for i in txt: w_f.write(i[num] + "\n")
!cut -c 1 popular-names.txt > col1.txt !cut -c 2 popular-names.txt > col2.txt
13. col1.txtとcol2.txtをマージ
12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.
python
with open("col1-col2.txt", "w") as w_f, open("col1.txt") as col1_f, open("col2.txt") as col2_f: col1 = col1_f.readlines() col2 = col2_f.readlines() for i, j in zip(col1, col2): w_f.write(i.replace("\n", "") + j)
unix
!paste -d "\t" col1.txt col2.txt > col1-col2.txt
14. 先頭からN行を出力
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ.
python
N = input() with open(txt_file) as f: txt = f.readlines() for i in range(int(N)): print(txt[i].replace("\n", ""))
5
Mary F 7065 1880
Anna F 2604 1880
Emma F 2003 1880
Elizabeth F 1939 1880
Minnie F 1746 1880
unix
!head -n 5 popular-names.txt
Mary F 7065 1880
Anna F 2604 1880
Emma F 2003 1880
Elizabeth F 1939 1880
Minnie F 1746 1880
15. 末尾のN行を出力
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.
python
N = input() with open(txt_file) as f: txt = f.readlines() for i in range(int(N)): print(txt[len(txt) - int(N) + i].replace("\n", ""))
5
Benjamin M 13381 2018
Elijah M 12886 2018
Lucas M 12585 2018
Mason M 12435 2018
Logan M 12352 2018
unix
!tail -n 5 popular-names.txt
Benjamin M 13381 2018
Elijah M 12886 2018
Lucas M 12585 2018
Mason M 12435 2018
Logan M 12352 2018
16. ファイルをN分割する【Skip】
自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ.
python
#N = input() N = 1000 with open(txt_file) as f: txt = f.readlines() file_num = int(len(txt) / N) + 1 #for i in range(file_num): # ??????????
unix
!split -l 1000 popular-names.txt split_file
17. 1列目の文字列の異なり
1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはcut, sort, uniqコマンドを用いよ.
python
with open(txt_file) as f: txt = f.readlines() letter_list = [] for i in txt: letter_list.append(i[0]) print(sorted(list(set(letter_list))))
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'V', 'W']
unix
※うまく行かなかったのでココを参照。「連続していない離れた重複行も削除したければ、sortコマンドコマンドで予めソートする必要がある。その代わり順番は保存されない。」らしい。
!cut -c 1 popular-names.txt | sort | uniq
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
R
S
T
V
W
18. 各行を3コラム目の数値の降順にソート
各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).
python
# pandas使って良いんじゃんと気づいた import pandas as pd txt = pd.read_table("popular-names.txt", header=None, names=["name", "sex", "num", "era"]) txt.sort_values("num", ascending=False).head()
name | sex | num | era | |
---|---|---|---|---|
1340 | Linda | F | 99689 | 1947 |
1360 | Linda | F | 96211 | 1948 |
1350 | James | M | 94757 | 1947 |
1550 | Michael | M | 92704 | 1957 |
1351 | Robert | M | 91640 | 1947 |
unix
!sort -k 3nr,3 popular-names.txt | head -n 5
Linda F 99689 1947
Linda F 96211 1948
James M 94757 1947
Michael M 92704 1957
Robert M 91640 1947
sort: write failed: 'standard output': Broken pipe
sort: write error
19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる
各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.
python
import pandas as pd df = pd.read_table("popular-names.txt", header=None, names=["name", "sex", "num", "era"]) df["name"].str[:1].value_counts(ascending=False).head()
J 448
M 407
R 211
E 211
A 211
Name: name, dtype: int64
unix
!cut -c 1 popular-names.txt | sort | uniq -c | sort -rn | head -n 5
448 J
407 M
211 R
211 E
211 A