はじめに
Pythonを勉強するため、東京工業大学の岡崎教授が出題されている言語処理100本ノック 2015を解いていきます。
より深く理解するため、別解や利用したライブラリの解説もまとめていきます。
環境
Python3.6
OS : mac
2章からUNIXコマンドの問題ですが、macもターミナルから利用できるようです。
問題
hightemp.txtは,日本の最高気温の記録を「都道府県」「地点」「℃」「日」のタブ区切り形式で格納したファイルである.以下の処理を行うプログラムを作成し,hightemp.txtを入力ファイルとして実行せよ.さらに,同様の処理をUNIXコマンドでも実行し,プログラムの実行結果を確認せよ.
19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる
各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.
解答:Python
points
- 1列目の配列を取り出す
- 空白文字などは削除しておく
- それぞれの個数を求める
- 多い順にソートする
program
import collections
def read_file(file_name):
with open(file_name, 'r') as file:
return file.read()
lines = read_file('hightemp.txt').split('')
# 空行の削除
lines = list(filter(lambda line: line != '', lines))
# 行をタブで分割
lines = list(map(lambda line: line.split('\t'), lines))
# 1列目の取り出し
cal1 = list(map(lambda line: line[0].strip(), lines))
# 要素と数を多い順に取り出す。
counted_cal1 = collections.Counter(cal1).most_common()
print(counted_cal1)
# => [('埼玉県', 3), ('山形県', 3), ('山梨県', 3), ('群馬県', 3), ('岐阜県', 2), ('静岡県', 2), ('愛知県', 2), ('千葉県', 2), ('高知県', 1), ('和歌山県', 1), ('愛媛県', 1), ('大阪府', 1)]
# タブ区切りで行を結合
counted_cal1 = list(map(lambda x: f'{x[1]}\t{x[0]}', counted_cal1))
print("".join(counted_cal1))
出力
3 埼玉県
3 山形県
3 山梨県
3 群馬県
2 岐阜県
2 静岡県
2 愛知県
2 千葉県
1 高知県
1 和歌山県
1 愛媛県
1 大阪府
解説
入力を2次元配列にするまでは、前回までの問題と同じです。
# 1列目の取り出し
cal1 = list(map(lambda line: line[0].strip(), lines))
この行で、1列目を取り出しつつ、空白文字も除いておきます。
import collections
# 要素と数を多い順に取り出す。
counted_cal1 = collections.Counter(cal1).most_common()
print(counted_cal1)
# => [('埼玉県', 3), ('山形県', 3), ('山梨県', 3), ('群馬県', 3), ('岐阜県', 2), ('静岡県', 2), ('愛知県', 2), ('千葉県', 2), ('高知県', 1), ('和歌山県', 1), ('愛媛県', 1), ('大阪府', 1)]
カウントの方法を探していたら、collections.Counter()
に行き着いてしまいました。
これは、要素を辞書のキーとして保存し、そのカウントを辞書の値として保存します。
しかも、most_common()
の関数で数の多い順に並び替えてもくれます。
つまり、ほぼ答えです。。。
1行で書けてしまいました。
# 要素の数を数える
counted_cal1 = [(x, cal1.count(x)) for x in set(cal1)]
# 指定列で逆順ソート
counted_cal1 = sorted(counted_cal1, key=lambda x: x[1], reverse=True)
一応こんな感じで、set()で集合を出して、連想配列の中で数を数えて。。。と考えていましたが、collections
を使った方がスマートですね。
# タブ区切りで行を結合
counted_cal1 = list(map(lambda x: f'{x[1]}\t{x[0]}', counted_cal1))
print("".join(counted_cal1))
最後に、書式を整えて出力します。
解答:UNIXコマンド
考え中。。。
続いての記事
次の問題:20. JSONデータの読み込み
Python:ファイルダウンロードの進行状況とファイルサイズを表示する方法。urllib
Pythonschedule2024-02-27
【Python】tqdmでforの進捗状況を表示する
PythonColabolatoryschedule2021-02-16
学習済みの日本語単語ベクトルをColabolatoryで試してみる
自然言語処理PythonColabolatoryschedule2021-02-04
Unity ML-Agentsで新しく学習環境を作る
Unity機械学習C#PythonDeepLearningschedule2021-01-22
27. 内部リンクの除去
自然言語処理100本ノックPythonschedule2020-03-17