ギークなエンジニアを目指す男

機械学習系の知識を蓄えようとするブログ

【言語処理100本ノック 2020】 2章をPythonで解いた

f:id:taxa_program:20200502163654p:plain

こんにちは。たかぱい(@takapy0210)です。

本エントリは言語処理100本ノック 2020の2章を解いてみたので、それの備忘です。

nlp100.github.io

例によってコードはGithubに置いてあります。

github.com

第2章: UNIXコマンド

popular-names.txtは,アメリカで生まれた赤ちゃんの「名前」「性別」「人数」「年」をタブ区切り形式で格納したファイルである.以下の処理を行うプログラムを作成し,popular-names.txtを入力ファイルとして実行せよ.さらに,同様の処理をUNIXコマンドでも実行し,プログラムの実行結果を確認せよ.

10. 行数のカウント

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

df = pd.read_csv('popular-names.txt', sep='\t', header=None)
print(len(df.index))

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

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

df = pd.read_csv('popular-names.txt', sep='\t', header=None)
df.to_csv('ans_11.txt', sep=' ', index=False, header=False)

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', sep='\t', header=None)
df.iloc[:,0].to_csv('col1.txt', index=False, header=False)
df.iloc[:,1].to_csv('col2.txt', index=False, header=False)

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

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

df_col1 = pd.read_csv('col1.txt', header=None)
df_col2 = pd.read_csv('col2.txt', header=None)
df = pd.concat([df_col1, df_col2], axis=1)
df.to_csv('ans_13.txt', sep='\t', index=False, header=False)

14. 先頭からN行を出力

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

Usage
>> python ans_14.py --n=5
"""
import pandas as pd
import fire


def main(n):
    df = pd.read_csv('popular-names.txt', sep='\t', header=None, nrows=n)
    print(df)


if __name__ == '__main__':
    fire.Fire(main)

fireを使うと、コマンドライン引数の取り扱いが楽になるのでオススメです

github.com

15. 末尾のN行を出力

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

Usage
>> python ans_15.py --n=5
"""
import pandas as pd
import fire


def main(n):
    df = pd.read_csv('popular-names.txt', sep='\t', header=None)
    print(df.tail(n))


if __name__ == '__main__':
    fire.Fire(main)

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

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

Usage
>> python ans_16.py --n=5
"""
import pandas as pd
import fire


def main(n):
    df = pd.read_csv('popular-names.txt', sep='\t', header=None)
    for i, df in df.groupby(df.index // (len(df.index)/(n))):
        df.to_csv("ans_16-{}.txt".format(int(i+1)), sep='\t', index=False, header=False)


if __name__ == '__main__':
    fire.Fire(main)

groupbyを使って分割しています。

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

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

df = pd.read_csv('popular-names.txt', sep='\t', header=None)
print(set(df.iloc[:,0].tolist()))

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

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

df = pd.read_csv('popular-names.txt', sep='\t', header=None)
df.sort_values(2, ascending=False).to_csv('ans_18.txt', sep='\t', index=False, header=False)

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

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

df = pd.read_csv('popular-names.txt', sep='\t', header=None)
df['count'] = df.groupby(0)[0].transform('count')
df.sort_values(['count', 0], ascending=False).to_csv('ans_19.txt', sep='\t', index=False, header=False)