はじめに
満を持して言語処理100本ノック 2020が公開されたので早速やってみます。1章は2015と全く同じようなので(しかもちょうどそこだけはやっていたので)、2章からやっていきます。
いくつかQiitaにも既に記事は上がっていますが、自然言語処理の概観が学べる上に、序盤は言語処理に限らずLinux初心者や竸プロ初心者にも役に立つと思います。
第2章: UNIXコマンド
popular-names.txtは,アメリカで生まれた赤ちゃんの「名前」「性別」「人数」「年」をタブ区切り形式で格納したファイルである.以下の処理を行うプログラムを作成し,popular-names.txtを入力ファイルとして実行せよ.さらに,同様の処理をUNIXコマンドでも実行し,プログラムの実行結果を確認せよ.
10. 行数のカウント
行数をカウントせよ.確認にはwcコマンドを用いよ.
import pandas as pd
df = pd.read_csv('popular-names.txt', delimiter='\t', header=None)
print(len(df.index))
wc -l popular-names.txt
11. タブをスペースに置換
タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.
import pandas as pd
df = pd.read_csv('popular-names.txt', delimiter='\t', header=None)
df.to_csv('popular-names-space.txt', sep=' ', index=False, header=None)
sed -e $'s/\t/ /g' popular-names.txt > popular-names-space.txt
※正規表現の部分はMac(BSD)用です。Linuxでは動作しないかと思います。
12. 1列目をcol1.txtに,2列目をcol2.txtに保存
各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.
import pandas as pd
df = pd.read_csv('popular-names.txt', delimiter='\t', header=None)
df[0].to_csv('col1.txt', index=False, header=None)
df[1].to_csv('col2.txt', index=False, header=None)
cut -f 1 popular-names.txt > col1.txt
cut -f 2 popular-names.txt > col2.txt
13. col1.txtとcol2.txtをマージ
12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.
import pandas as pd
df1 = pd.read_csv('col1.txt', header=None)
df2 = pd.read_csv('col2.txt', header=None)
df_concat = pd.concat([df1, df2], axis=1)
df_concat.to_csv('col3.txt', sep='\t', index=False, header=None)
paste col1.txt col2.txt > col3.txt
14. 先頭からN行を出力
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ.
import pandas as pd
n = int(input())
df = pd.read_csv('popular-names.txt', delimiter='\t', header=None)
print(df.head(n))
head -5 popular-names.txt
15. 末尾のN行を出力
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.
import pandas as pd
n = int(input())
df = pd.read_csv('popular-names.txt', delimiter='\t', header=None)
print(df.tail(n))
tail -5 popular-names.txt
16. ファイルをN分割する
自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ.
import pandas as pd
n = int(input())
df = pd.read_csv('popular-names.txt', delimiter='\t', header=None)
for i in range(1, len(df) // n + 1):
df[n*i:n*i+n:].to_csv('popular-names' + str(i) + '.txt', index=False, header=None)
ここはあまり美しくないですが、DataFrameを行ごとに分割する簡潔な書き方がなさそうだったので。
split -l 200 popular-names.txt popular-names-
17. 1列目の文字列の異なり
1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはcut, sort, uniqコマンドを用いよ.
import pandas as pd
df = pd.read_csv('popular-names.txt', delimiter='\t', header=None)
print(set(list(df[0])))
cut -f 1 popular-names.txt | sort | uniq
uniq
は事前にソートが必要。
18. 各行を3コラム目の数値の降順にソート
各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).
import pandas as pd
df = pd.read_csv('popular-names.txt', delimiter='\t', header=None)
print(df.sort_values(2, ascending=False))
sort -n -r -k 3 popular-names.txt | head -10
※出力が長くなってしまうためhead -10
で10行に絞っています
19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる
各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.
import pandas as pd
df = pd.read_csv('popular-names.txt', delimiter='\t', header=None)
print(df[0].value_counts())
cut -f 1 popular-names.txt | sort | uniq -c | sort -n -r -k 1 | head -10
※出力が長くなってしまうためhead -10
で10行に絞っています
おわりに
2章で学べること
- pandas.DataFrameの基礎
- Unixコマンドでの文字列・ファイル操作
- sed
- cut
- paste
- head
- tail
- split
- sort
- uniq