こんにちは。たかぱい(@takapy0210)です。
本エントリは言語処理100本ノック 2020の2章を解いてみたので、それの備忘です。
例によってコードはGithubに置いてあります。
第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
を使うと、コマンドライン引数の取り扱いが楽になるのでオススメです
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)