サイトデザインを新しくしました!

【Python】気象庁の気象データから、日付と平均気温を抽出するサンプルコード

はじめに

先日、Pythonを使って、データを解析する機会がありました。そんな時、「簡単なサンプルコードがあったら便利だ」と感じたため、ブログに残しておこうと思います。

サンプルコードは好きに使ってもらって構いません(大したコードではないので)「もっとこうしたらいいのに」というご意見がありましたら、コメント欄までお願いいたします。

私の環境は以下の通りです。

  • Windows 10 64bit
  • Anaconda3 5.3.0
  • Python 3.7.0

例題

今回、例として用意した解析元のデータは、過去の気象データです。この気象データは、気象庁のホームページから誰でも無料でダウンロードできます。

参考 過去の気象データ・ダウンロード気象庁

ここでダウンロードできる気象データはCSVです。Pythonはモジュールを使えばCSVも簡単に使いこなせるのですが、今回はテキストに落とし込んでいます。(CSVファイルを開いて、テキストエディタにコピペしただけです)

以下に、解析元データ(気象データ)の一部抜粋を添付します。
この気象データを今回3つ用意しました。

weather_data1.txt / weather_data2.txt / weather_data3.txt :

txt
https://www.data.jma.go.jp/gmd/risk/obsdl/index.php
ダウンロードした時刻:2018/11/13 00:02:19									
									
	横浜	横浜	横浜	横浜	横浜	横浜	横浜	横浜	横浜
年月日	平均気温(℃)	平均気温(℃)	平均気温(℃)	最高気温(℃)	最高気温(℃)	最高気温(℃)	最低気温(℃)	最低気温(℃)	最低気温(℃)
									
		品質情報	均質番号		品質情報	均質番号		品質情報	均質番号
2017/11/12	13	8	1	16.3	8	1	10.4	8	1
2017/11/13	12.4	8	1	16.8	8	1	8.7	8	1
2017/11/14	12.8	8	1	15	8	1	11.1	8	1
2017/11/15	13.7	8	1	17.3	8	1	11.2	8	1
2017/11/16	12.5	8	1	16.7	8	1	10	8	1
2017/11/17	10.9	8	1	13.7	8	1	7.4	8	1
2017/11/18	11.7	8	1	15.2	8	1	8.9	8	1
2017/11/19	9.5	8	1	12.4	8	1	7.3	8	1
2017/11/20	7.7	8	1	11.1	8	1	5.4	8	1
2017/11/21	8.9	8	1	12.2	8	1	5.3	8	1
2017/11/22	7.7	8	1	12.4	8	1	4.1	8	1
2017/11/23	10.1	8	1	15	8	1	6.2	8	1
2017/11/24	11	8	1	15.5	8	1	7.9	8	1
2017/11/25	10.5	8	1	15.3	8	1	6.1	8	1
2017/11/26	12.8	8	1	18.1	8	1	5.1	8	1
2017/11/27	12.4	8	1	14.8	8	1	9.8	8	1
2017/11/28	12.3	8	1	15	8	1	9.9	8	1
2017/11/29	13.3	8	1	17.3	8	1	8.4	8	1
2017/11/30	12.3	8	1	15.1	8	1	8.8	8	1

ここから日付と平均気温のみを抽出することが、今回の課題です。日付は一番左の列、平均気温は日付の隣の列です。他は不要なデータとします。

サンプルコード

サンプルコードは以下の通りです。

Python
import re
in_files = ['weather_data1',
            'weather_data2',
            'weather_data3']

for in_file in in_files:

    # ファイルオープン(withを使えばclose不要)
    with open(in_file+'.txt', 'r') as fr:

        # 1行ずつ読み込み
        for line in fr:

            # 日付のある行を探す
            m1 = re.match(r'([0-9]+/[0-9]+/[0-9]+)\t([0-9]+\.*[0-9]*)\t', line)
            if m1:
                out_file = in_file+'convert.txt'
                # 日時と平均気温だけを出力
                with open(out_file, 'a') as fa:
                    fa.write(m1.group(1))
                    fa.write('\t')
                    fa.write(m1.group(2))
                    fa.write('\n')

一つ一つ解説します。

Python
import re

これは、正規表現を使うようにするためのライブラリです。

Python
in_files = ['weather_data1',
            'weather_data2',
            'weather_data3']

これはファイル名です。今回ファイルが3つあるので、in_filesというリストに格納しています。

Python
for in_file in in_files:
    # ファイルオープン(withを使えばclose不要)
    with open(in_file+'.txt', 'r') as fr:

        # 1行ずつ読み込み
        for line in fr:

in_filesというリストから、ファイル名を一つ取り出してin_fileに入れています。
with openを使ってファイルを開きます。第一引数にはファイル名を、第二引数は読み込み用でファイルを開くことを指定しています。

‘r’ とすれば、読み込みモード
‘w’ とすれば、書き込みモード
‘a’ とすれば、追記モード

ちなみにwith openで開いたファイルは、Closeが不要です。
as frで、開いたファイルを以降、frとして扱います。
for line in frで、1行ずつファイルを読み込むことができます。

Python
m1 = re.match(r'([0-9]+/[0-9]+/[0-9]+)\t([0-9]+\.*[0-9]*)\t', line)

re.matchは、文字列の先頭がパターンにマッチするかを調べます。
第一引数は検索したい正規表現を、第二引数は検索元を入力します。

正規表現の中で、カッコで囲んでいる箇所があります。こうすることで、カッコで囲まれた部分にマッチした文字列を、”group(番号(1始まり))”とするだけでタプルで取得できます。

今回は、日付をgroup(1)、気温をgroup(2)としています。この検索結果をm1に格納します。もし見つからなければm1にはNoneが入ります。

Python
if m1:
    out_file = in_file+'convert.txt'
    # 日時と平均気温だけを出力
    with open(out_file, 'a') as fa:
        fa.write(m1.group(1))
        fa.write('\t')
        fa.write(m1.group(2))
        fa.write('\n')

m1がNone以外、すなわち見つかった場合、日付と平均気温を出力します。
まず出力ファイル名を決めます。今回はファイル名に’convert.txt’を追加したものにしました。

出力ファイルを”追記モード”で開いて、それをfaとして扱います。
次にfa.writeで出力ファイルに書き込みます。

m1.group(1)は日付を、m1.group(2)は平均気温を意味します。
日付と平均気温の間には、タブを入れました。最後に改行をしています。

出力結果

以下が出力結果です。ファイルと同じフォルダに、出力ファイルが生成されていると思います。日付と平均気温だけが綺麗に抽出できています。

weather_data1convert.txt / weather_data2convert.txt / weather_data3convert.txt

text
2017/11/12	13
2017/11/13	12.4
2017/11/14	12.8
2017/11/15	13.7
2017/11/16	12.5
2017/11/17	10.9
2017/11/18	11.7
2017/11/19	9.5
2017/11/20	7.7
2017/11/21	8.9
2017/11/22	7.7
2017/11/23	10.1
2017/11/24	11
2017/11/25	10.5
2017/11/26	12.8
2017/11/27	12.4
2017/11/28	12.3
2017/11/29	13.3
2017/11/30	12.3
2017/12/1	9.3
2017/12/2	8.5
2017/12/3	9.1
2017/12/4	9.7
2017/12/5	10.1
2017/12/6	8.1
2017/12/7	7.6
2017/12/8	6.5
2017/12/9	7
2017/12/10	9.3

以上です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です