[n番煎じ] 言語処理100本ノック 2015 第2章 with Python

# はじめに
院の講義に向けた準備や細かいタスクの影響で前回のから更新が遅くなりましたが，第2章の進捗です．

もし何かためになるアドバイス等があれば優しいコメントを残して頂けると幸いですm(_ _)m

・[第1章](https://qiita.com/3000manJPY/items/40dcb9994eedfa7f33dd)

コードだけは[コチラ](https://github.com/3000manJPY/NLP100Knocks)へ．

# 第2章: UNIXコマンドの基礎
>研究やデータ分析において便利なUNIXツールを体験します．これらの再実装を通じて，プログラミング能力を高めつつ，既存のツールのエコシステムを体感します．
>キーワード：head, tail, cut, paste, split, sort, uniq, sed, tr, expand

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

# 問題10 行数のカウント
> 行数をカウントせよ．確認にはwcコマンドを用いよ．

## プログラム

```python
#!/usr/local/bin python3
# -*- coding: utf-8 -*-

def count_file_line_num(filepath: str) -> int:
    """
    渡されたファイルの行数をカウントして返す関数

    Parameter
    ----------
    filepath: str
        ファイルパス

    Return
    ----------
    ファイルの行数
    """
    with open(filepath, 'r') as f:
        return sum(1 for line in f)

def main():
    filepath = './hightemp.txt'

    line_num = count_file_line_num(filepath)
  
    print('行数: {}'.format(line_num))

if __name__ == '__main__':
    main()
```

```console
$ python3 10.py 
行数: 24
```

## 確認コマンド

```console
$ wc -l (または --line) hightemp.txt
```
```console
$ wc -l hightemp.txt
24 hightemp.txt
```

# 問題11 タブをスペースに置換
> タブ1文字につきスペース1文字に置換せよ．確認にはsedコマンド，trコマンド，もしくはexpandコマンドを用いよ．

## プログラム

```python
#!/usr/local/bin python3
# -*- coding: utf-8 -*-

def replace_delimiter(filepath: str, pre_delimiter: str, new_delimiter: str) -> list:
    """
    ファイルのデリミタ文字を置換する関数

    Parameters
    ----------
    filepath: str
        入力ファイルパス
    pre_delimiter, new_delimiter: str
        現在/新規のデリミタ文字

    Return
    ----------
    置換後の文字列のリスト
    """
    with open(filepath, 'r') as f:
        return [line.replace(pre_delimiter, new_delimiter) for line in f]

def main():
    filepath = './hightemp.txt'

    replaced_strs = replace_delimiter(filepath, '\t', ' ')

    for el in replaced_strs:
        print(el, end = '')

if __name__ == '__main__':
    main()
```

```console
$ python3 11.py 
高知県 江川崎 41 2013-08-12
埼玉県 熊谷 40.9 2007-08-16
岐阜県 多治見 40.9 2007-08-16
山形県 山形 40.8 1933-07-25
山梨県 甲府 40.7 2013-08-10
和歌山県 かつらぎ 40.6 1994-08-08
静岡県 天竜 40.6 1994-08-04
山梨県 勝沼 40.5 2013-08-10
埼玉県 越谷 40.4 2007-08-16
群馬県 館林 40.3 2007-08-16
群馬県 上里見 40.3 1998-07-04
愛知県 愛西 40.3 1994-08-05
千葉県 牛久 40.2 2004-07-20
静岡県 佐久間 40.2 2001-07-24
愛媛県 宇和島 40.2 1927-07-22
山形県 酒田 40.1 1978-08-03
岐阜県 美濃 40 2007-08-16
群馬県 前橋 40 2001-07-24
千葉県 茂原 39.9 2013-08-11
埼玉県 鳩山 39.9 1997-07-05
大阪府 豊中 39.9 1994-08-08
山梨県 大月 39.9 1990-07-19
山形県 鶴岡 39.9 1978-08-03
愛知県 名古屋 39.9 1942-08-02
```

## 確認コマンド

```console
[1] $ sed -e 's/\t/ /g' ./hightemp.txt > ./hightemp_sed.txt
[2] $ cat ./hightemp.txt | tr '\t' ' ' > ./hightemp_tr.txt
[3] $ expand -t 1 ./hightemp.txt > ./hightemp_expand.txt
```
```console
$ sed -e 's/\t/ /g' ./hightemp.txt > ./hightemp_sed.txt
$ cat hightemp_sed.txt
高知県 江川崎 41 2013-08-12
埼玉県 熊谷 40.9 2007-08-16
岐阜県 多治見 40.9 2007-08-16
山形県 山形 40.8 1933-07-25
山梨県 甲府 40.7 2013-08-10
和歌山県 かつらぎ 40.6 1994-08-08
静岡県 天竜 40.6 1994-08-04
山梨県 勝沼 40.5 2013-08-10
埼玉県 越谷 40.4 2007-08-16
群馬県 館林 40.3 2007-08-16
群馬県 上里見 40.3 1998-07-04
愛知県 愛西 40.3 1994-08-05
千葉県 牛久 40.2 2004-07-20
静岡県 佐久間 40.2 2001-07-24
愛媛県 宇和島 40.2 1927-07-22
山形県 酒田 40.1 1978-08-03
岐阜県 美濃 40 2007-08-16
群馬県 前橋 40 2001-07-24
千葉県 茂原 39.9 2013-08-11
埼玉県 鳩山 39.9 1997-07-05
大阪府 豊中 39.9 1994-08-08
山梨県 大月 39.9 1990-07-19
山形県 鶴岡 39.9 1978-08-03
愛知県 名古屋 39.9 1942-08-02
```

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

## プログラム

```python
#!/usr/local/bin python3
# -*- coding: utf-8 -*-

def extract_column(in_filepath: str, out_filepath: str, delimiter: str, col_num: int):
    """
    入力ファイルの指定カラムだけ出力ファイルに保存する関数

    Parameters
    ----------
    in_filepath, out_filepath: str
        入力/出力ファイルパス
    delimiter: str
        デリミタ文字
    col_num: int
        抽出したいカラムの番号
    """
    with open(in_filepath, 'r') as in_file, open(out_filepath, 'w') as out_file:
        for line in in_file:
            line_split = line.split(delimiter)
            line_split[-1] = line_split[-1].rstrip('\n')
            out_file.write(line_split[col_num-1] + '\n')

def main():
    in_filepath = './hightemp.txt'

    out_filepath = './col1.txt'
    extract_column(in_filepath, out_filepath, '\t', 1)

    out_filepath = './col2.txt'
    extract_column(in_filepath, out_filepath, '\t', 2)

if __name__ == '__main__':
    main()
```

```console
$ python3 12.py 
$ cat col1.txt 
高知県
埼玉県
岐阜県
山形県
山梨県
和歌山県
静岡県
山梨県
埼玉県
群馬県
群馬県
愛知県
千葉県
静岡県
愛媛県
山形県
岐阜県
群馬県
千葉県
埼玉県
大阪府
山梨県
山形県
愛知県
$ cat col2.txt
江川崎
熊谷
多治見
山形
甲府
かつらぎ
天竜
勝沼
越谷
館林
上里見
愛西
牛久
佐久間
宇和島
酒田
美濃
前橋
茂原
鳩山
豊中
大月
鶴岡
名古屋
```

## 確認コマンド

```console
$ cut -f 1 ./hightemp.txt > col1.txt
$ cut -f 2 ./hightemp.txt > col2.txt
```
```console
$ cut -f 1 ./hightemp.txt > col1.txt
$ cut -f 2 ./hightemp.txt > col2.txt
$ cat col1.txt 
高知県
埼玉県
岐阜県
山形県
山梨県
和歌山県
静岡県
山梨県
埼玉県
群馬県
群馬県
愛知県
千葉県
静岡県
愛媛県
山形県
岐阜県
群馬県
千葉県
埼玉県
大阪府
山梨県
山形県
愛知県
$ cat col2.txt
江川崎
熊谷
多治見
山形
甲府
かつらぎ
天竜
勝沼
越谷
館林
上里見
愛西
牛久
佐久間
宇和島
酒田
美濃
前橋
茂原
鳩山
豊中
大月
鶴岡
名古屋
```

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

## プログラム

```python
#!/usr/local/bin python3
# -*- coding: utf-8 -*-

def merge_file_contents(tgt1_filepath: str, tgt2_filepath: str, delimiter: str, out_filepath: str):
    """
    2つのターゲットファイルの中身をマージする関数

    Parameters
    ----------
    tgt1_filepath, tgt2_filepath: str
        マージ元ファイルパス
    delimiter: str
        デリミタ文字
    out_filepath: str
        マージ先のファイルパス
    """
    with open(tgt1_filepath, 'r') as tgt1_file, open(tgt2_filepath, 'r') as tgt2_file, open(out_filepath, 'w') as out_file:
        for idx, (el1, el2) in enumerate(zip(tgt1_file, tgt2_file)):
            out_file.write(el1.rstrip('\n') + delimiter + el2)

def main():
    tgt1_filepath = './col1.txt'
    tgt2_filepath = './col2.txt'
    out_filepath = './merged_col.txt'

    merge_file_contents(tgt1_filepath, tgt2_filepath, '\t', out_filepath)

if __name__ == '__main__':
    main()
```

```console
$ python3 13.py 
$ cat merged_col.txt
高知県  江川崎
埼玉県  熊谷
岐阜県  多治見
山形県  山形
山梨県  甲府
和歌山県        かつらぎ
静岡県  天竜
山梨県  勝沼
埼玉県  越谷
群馬県  館林
群馬県  上里見
愛知県  愛西
千葉県  牛久
静岡県  佐久間
愛媛県  宇和島
山形県  酒田
岐阜県  美濃
群馬県  前橋
千葉県  茂原
埼玉県  鳩山
大阪府  豊中
山梨県  大月
山形県  鶴岡
愛知県  名古屋
```

## 確認コマンド

```console
$ paste col1.txt col2.txt > merged_col.txt
```
```console
$ paste col1.txt col2.txt > merged_col.txt
$ cat merged_col.txt 
高知県  江川崎
埼玉県  熊谷
岐阜県  多治見
山形県  山形
山梨県  甲府
和歌山県        かつらぎ
静岡県  天竜
山梨県  勝沼
埼玉県  越谷
群馬県  館林
群馬県  上里見
愛知県  愛西
千葉県  牛久
静岡県  佐久間
愛媛県  宇和島
山形県  酒田
岐阜県  美濃
群馬県  前橋
千葉県  茂原
埼玉県  鳩山
大阪府  豊中
山梨県  大月
山形県  鶴岡
愛知県  名古屋
```

# 問題14 先頭からN行を出力
> 自然数Nをコマンドライン引数などの手段で受け取り，入力のうち先頭のN行だけを表示せよ．確認にはheadコマンドを用いよ．

## プログラム

```python
#!/usr/local/bin python3
# -*- coding: utf-8 -*-

import sys

def extract_head_n(filepath: str, line_num: int) -> list:
    """
    入力ファイルの先頭から指定行数だけ抽出する関数

    Parameters
    ----------
    filepath: str
        入力ファイルパス
    line_num: int
        抽出する行数

    Return
    ----------
    先頭n行のリスト
    """
    with open(filepath, 'r') as f:
        file_content = f.readlines()
        return file_content[0:line_num]

def main():
    in_filepath = './hightemp.txt'
    n = int(sys.argv[1])

    head_n = extract_head_n(in_filepath, n)

    for el in head_n:
        print(el, end = '') 

if __name__ == '__main__':
    main()

```

```console
$ python3 14.py 5
高知県  江川崎  41      2013-08-12
埼玉県  熊谷    40.9    2007-08-16
岐阜県  多治見  40.9    2007-08-16
山形県  山形    40.8    1933-07-25
山梨県  甲府    40.7    2013-08-10
```

## 確認コマンド

```console
$ cat hightemp.txt | head -n 5
```
```console
$ cat hightemp.txt | head -n 5
高知県  江川崎  41      2013-08-12
埼玉県  熊谷    40.9    2007-08-16
岐阜県  多治見  40.9    2007-08-16
山形県  山形    40.8    1933-07-25
山梨県  甲府    40.7    2013-08-10
```

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

## プログラム

```python
#!/usr/local/bin python3
# -*- coding: utf-8 -*-

import sys

def extract_tail_n(filepath: str, line_num: int) -> list:
    """
    入力ファイルの末尾から指定行数だけ抽出する関数

    Parameters
    ----------
    filepath: str
        入力ファイルパス
    line_num: int
        抽出する行数

    Return
    ----------
    末尾n行のリスト
    """
    with open(filepath, 'r') as f:
        file_content = f.readlines()
        return file_content[-line_num:]

def main():
    in_filepath = './hightemp.txt'
    n = int(sys.argv[1])

    tail_n = extract_tail_n(in_filepath, n)

    for el in tail_n:
        print(el, end = '') 

if __name__ == '__main__':
    main()
```

```console
$ python3 15.py 5
埼玉県  鳩山    39.9    1997-07-05
大阪府  豊中    39.9    1994-08-08
山梨県  大月    39.9    1990-07-19
山形県  鶴岡    39.9    1978-08-03
愛知県  名古屋  39.9    1942-08-02
```

## 確認コマンド

```console
$ cat hightemp.txt | tail -n 5
```
```console
$ cat hightemp.txt | tail -n 5
埼玉県  鳩山    39.9    1997-07-05
大阪府  豊中    39.9    1994-08-08
山梨県  大月    39.9    1990-07-19
山形県  鶴岡    39.9    1978-08-03
愛知県  名古屋  39.9    1942-08-02
```

# 問題16 ファイルをN分割する
> 自然数Nをコマンドライン引数などの手段で受け取り，入力のファイルを行単位でN分割せよ．同様の処理をsplitコマンドで実現せよ．

## プログラム

```python
#!/usr/local/bin python3
# -*- coding: utf-8 -*-

import sys

def count_file_line_num(filepath: str) -> int:
    """
    渡されたファイルの行数をカウントして返す関数

    Parameter
    ----------
    filepath: str
        ファイルパス

    Return
    ----------
    ファイルの行数
    """
    with open(filepath, 'r') as f:
        return sum(1 for line in f)

def split_file_into_n(in_filepath: str, out_filepath: str, split_num: int):
    """
    入力ファイルを指定数で分割する関数

    Parameters
    ----------
    in_filepath: str
        入力ファイルパス
    out_filepath: str
        出力ファイルのパス
    split_num: int
        抽出する行数
    """
    origin_line_num = count_file_line_num(in_filepath)
    new_line_num = int(origin_line_num / split_num)
    remainder = origin_line_num % split_num
    
    with open(in_filepath, 'r') as in_file:
        file_content = in_file.readlines()
    
    for idx in range(split_num):
        with open(out_filepath + '{:02}'.format(idx), 'w') as out_file:
            if idx < remainder:
                out_file.write(''.join(file_content[((new_line_num + 1) * idx):((new_line_num + 1) * (idx + 1))]))
            else:
                out_file.write(''.join(file_content[((new_line_num * idx) + remainder):((new_line_num * (idx + 1)) + remainder)]))

def main():
    in_filepath = './hightemp.txt'
    out_filepath = './hightemp_split'
    n = int(sys.argv[1])

    split_file_into_n(in_filepath, out_filepath, n)

if __name__ == '__main__':
    main()

```

```console
$ python3 16.py 4
$ cat hightemp_split00
高知県  江川崎  41      2013-08-12
埼玉県  熊谷    40.9    2007-08-16
岐阜県  多治見  40.9    2007-08-16
山形県  山形    40.8    1933-07-25
山梨県  甲府    40.7    2013-08-10
和歌山県        かつらぎ        40.6    1994-08-08
$ cat hightemp_split01
静岡県  天竜    40.6    1994-08-04
山梨県  勝沼    40.5    2013-08-10
埼玉県  越谷    40.4    2007-08-16
群馬県  館林    40.3    2007-08-16
群馬県  上里見  40.3    1998-07-04
愛知県  愛西    40.3    1994-08-05
$ cat hightemp_split02
千葉県  牛久    40.2    2004-07-20
静岡県  佐久間  40.2    2001-07-24
愛媛県  宇和島  40.2    1927-07-22
山形県  酒田    40.1    1978-08-03
岐阜県  美濃    40      2007-08-16
群馬県  前橋    40      2001-07-24
$ cat hightemp_split03
千葉県  茂原    39.9    2013-08-11
埼玉県  鳩山    39.9    1997-07-05
大阪府  豊中    39.9    1994-08-08
山梨県  大月    39.9    1990-07-19
山形県  鶴岡    39.9    1978-08-03
愛知県  名古屋  39.9    1942-08-02
```

## 確認コマンド

```console
split -l 6 -d hightemp.txt hightemp_split
```
```console
$ split -l 6 -d hightemp.txt hightemp_split
$ cat hightemp_split00
高知県  江川崎  41      2013-08-12
埼玉県  熊谷    40.9    2007-08-16
岐阜県  多治見  40.9    2007-08-16
山形県  山形    40.8    1933-07-25
山梨県  甲府    40.7    2013-08-10
和歌山県        かつらぎ        40.6    1994-08-08
$ cat hightemp_split01
静岡県  天竜    40.6    1994-08-04
山梨県  勝沼    40.5    2013-08-10
埼玉県  越谷    40.4    2007-08-16
群馬県  館林    40.3    2007-08-16
群馬県  上里見  40.3    1998-07-04
愛知県  愛西    40.3    1994-08-05
$ cat hightemp_split02
千葉県  牛久    40.2    2004-07-20
静岡県  佐久間  40.2    2001-07-24
愛媛県  宇和島  40.2    1927-07-22
山形県  酒田    40.1    1978-08-03
岐阜県  美濃    40      2007-08-16
群馬県  前橋    40      2001-07-24
$ cat hightemp_split03
千葉県  茂原    39.9    2013-08-11
埼玉県  鳩山    39.9    1997-07-05
大阪府  豊中    39.9    1994-08-08
山梨県  大月    39.9    1990-07-19
山形県  鶴岡    39.9    1978-08-03
愛知県  名古屋  39.9    1942-08-02
```
(よく調べたら`-n`オプションで分割数が指定できた．)

# 問題17 １列目の文字列の異なり
> 1列目の文字列の種類（異なる文字列の集合）を求めよ．確認にはsort, uniqコマンドを用いよ．

## プログラム

```python
#!/usr/local/bin python3
# -*- coding: utf-8 -*-

def extract_differences_in_column_n(filepath: str, delimiter: str, col_num: int) -> list:
    """
    入力ファイルの指定カラムの異なり文字列の集合を返す関数

    Parameters
    ----------
    filepath: str
        入力ファイルパス
    delimiter: str
        デリミタ文字
    col_num: int
        指定カラム

    Return
    ----------
    differences: list
        指定カラムの異なり文字列の集合
    """
    differences = []

    with open(filepath, 'r') as f:
        for line in f:
            line_split = line.split(delimiter)
            line_split[-1] = line_split[-1].rstrip('\n')
            if not line_split[col_num-1] in differences:
                differences.append(line_split[col_num-1])

    return sorted(differences)

def main():
    in_filepath = './hightemp.txt'

    differences = extract_differences_in_column_n(in_filepath, '\t', 1)
    
    for el in differences:
        print(el)

if __name__ == '__main__':
    main()
```

```console
$ python3 17.py 
千葉県
和歌山県
埼玉県
大阪府
山形県
山梨県
岐阜県
愛媛県
愛知県
群馬県
静岡県
高知県
```

## 確認コマンド

```console
$ cat hightemp.txt | cut -f 1 | sort -u > hightemp17.txt
```
```console
$ cat hightemp.txt | cut -f 1 | sort -u > hightemp17.txt
$ cat hightemp17.txt 
愛知県
愛媛県
岐阜県
群馬県
高知県
埼玉県
山形県
山梨県
静岡県
千葉県
大阪府
和歌山県
```
(副次的な検索で[日本語のソートの面白い話](https://blog.jnito.com/entry/2014/12/03/185146)があったので参考までに．)

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

## プログラム

```python
#!/usr/local/bin python3
# -*- coding: utf-8 -*-

def sort_lines_with_n(filepath: str, delimiter: str, col_num: int, reverse: bool) -> list:
    """
    入力ファイルの指定カラムでソートする関数

    Parameters
    ----------
    filepath: str
        入力ファイルパス
    delimiter: str
        デリミタ文字
    col_num: int
        指定カラム
    reverse: bool
        逆順にするか否か

    Return
    ----------
    指定カラムの異なり文字列の集合
    """
    origin = []

    with open(filepath, 'r') as f:
        for line in f:
            line_split = line.split(delimiter)
            line_split[-1] = line_split[-1].rstrip('\n')
            origin.append(line_split)

    return sorted(origin, key = lambda x: x[col_num-1], reverse = reverse)

def main():
    in_filepath = './hightemp.txt'

    sorted_lines = sort_lines_with_n(in_filepath, '\t', 3, False)
    
    for line in sorted_lines:
        print('\t'.join(line))

if __name__ == '__main__':
    main()
```

```console
$ python3 18.py 
千葉県  茂原    39.9    2013-08-11
埼玉県  鳩山    39.9    1997-07-05
大阪府  豊中    39.9    1994-08-08
山梨県  大月    39.9    1990-07-19
山形県  鶴岡    39.9    1978-08-03
愛知県  名古屋  39.9    1942-08-02
岐阜県  美濃    40      2007-08-16
群馬県  前橋    40      2001-07-24
山形県  酒田    40.1    1978-08-03
千葉県  牛久    40.2    2004-07-20
静岡県  佐久間  40.2    2001-07-24
愛媛県  宇和島  40.2    1927-07-22
群馬県  館林    40.3    2007-08-16
群馬県  上里見  40.3    1998-07-04
愛知県  愛西    40.3    1994-08-05
埼玉県  越谷    40.4    2007-08-16
山梨県  勝沼    40.5    2013-08-10
和歌山県        かつらぎ        40.6    1994-08-08
静岡県  天竜    40.6    1994-08-04
山梨県  甲府    40.7    2013-08-10
山形県  山形    40.8    1933-07-25
埼玉県  熊谷    40.9    2007-08-16
岐阜県  多治見  40.9    2007-08-16
高知県  江川崎  41      2013-08-12
```

## 確認コマンド

```console
$ cat hightemp.txt | sort -k 3 > hightemp18.txt
```
```console
$ cat hightemp.txt | sort -k 3 > hightemp18.txt
$ cat hightemp18.txt 
愛知県  名古屋  39.9    1942-08-02
山形県  鶴岡    39.9    1978-08-03
山梨県  大月    39.9    1990-07-19
大阪府  豊中    39.9    1994-08-08
埼玉県  鳩山    39.9    1997-07-05
千葉県  茂原    39.9    2013-08-11
群馬県  前橋    40      2001-07-24
岐阜県  美濃    40      2007-08-16
山形県  酒田    40.1    1978-08-03
愛媛県  宇和島  40.2    1927-07-22
静岡県  佐久間  40.2    2001-07-24
千葉県  牛久    40.2    2004-07-20
愛知県  愛西    40.3    1994-08-05
群馬県  上里見  40.3    1998-07-04
群馬県  館林    40.3    2007-08-16
埼玉県  越谷    40.4    2007-08-16
山梨県  勝沼    40.5    2013-08-10
静岡県  天竜    40.6    1994-08-04
和歌山県        かつらぎ        40.6    1994-08-08
山梨県  甲府    40.7    2013-08-10
山形県  山形    40.8    1933-07-25
岐阜県  多治見  40.9    2007-08-16
埼玉県  熊谷    40.9    2007-08-16
高知県  江川崎  41      2013-08-12
```

# 問題19 各行の1コラム目の文字列の出現頻度を求め，出現頻度の高い順に並べる
> 各行の1列目の文字列の出現頻度を求め，その高い順に並べて表示せよ．確認にはcut, uniq, sortコマンドを用いよ．

## プログラム

```python
#!/usr/local/bin python3
# -*- coding: utf-8 -*-

def sort_elements_in_column_n(filepath: str, delimiter: str, col_num: int) -> list:
    """
    入力ファイルの指定カラムの異なり文字列の集合を返す関数

    Parameters
    ----------
    filepath: str
        入力ファイルパス
    delimiter: str
        デリミタ文字
    col_num: int
        指定カラム

    Return
    ----------
    differences: list
        指定カラムの異なり文字列の集合
    """
    elements = {}

    with open(filepath, 'r') as f:
        for line in f:
            line_split = line.split(delimiter)
            line_split[-1] = line_split[-1].rstrip('\n')
            if line_split[col_num-1] not in elements:
                elements[line_split[col_num-1]] = 1
            else:
                elements[line_split[col_num-1]] += 1

    return sorted(elements.items(), key = lambda x: x[1], reverse = True)

def main():
    in_filepath = './hightemp.txt'

    sorted_elements = sort_elements_in_column_n(in_filepath, '\t', 1)
    
    for el in sorted_elements:
        print('      {} {}'.format(el[1], el[0]))

if __name__ == '__main__':
    main()
```

```console
$ python3 19.py 
      3 埼玉県
      3 山形県
      3 山梨県
      3 群馬県
      2 岐阜県
      2 静岡県
      2 愛知県
      2 千葉県
      1 高知県
      1 和歌山県
      1 愛媛県
      1 大阪府
```

## 確認コマンド

```console
$ cat hightemp.txt | cut -f 1 | sort | uniq -c | sort -r > hightemp19.txt
```
```console
$ cat hightemp.txt | cut -f 1 | sort | uniq -c | sort -r > hightemp19.txt
$ cat hightemp19.txt 
      3 山梨県
      3 山形県
      3 埼玉県
      3 群馬県
      2 千葉県
      2 静岡県
      2 岐阜県
      2 愛知県
      1 和歌山県
      1 大阪府
      1 高知県
      1 愛媛県
```