Pythonで拡張アメダス新フォーマット(WEA2)を読む(3)

前回からの続きです。前回は気温のデータを読み込みました。今回は、WEA2からすべてのデータをまとめて読みます。

地点データをまとめて読み込む

WEA2の構造は前回のとおりです。この例では指定された地点(東京、363)のデータをまとめて読み込んでCSVの形式で保存します。

CSVの形式は値の種類ごとに時系列の「列」として出力します。地点番号や日平均のデータは取り除きます。

処理内容は以下の通りです。

  • numpyで1地点分のデータをまとめて読み込む
  • 10レコードに整形
  • Pandas/DataFrameに変換
  • 最初の3列(地点番号、値の種類、年)は使わないので削除
  • 最後の平均値366日分も同様に削除
  • 各値のリマークを削除
  • 列と行を入れ替える(WEA2は「行」ごとに値がまとまているので、時系列の「列」に変換する)
  • 値の単位を換算
  • 各列にラベルを付けてCSVへ保存する

Pythonコード

実際の処理は以下のようになります。この例では東京(363)を読み込んで出力しています。

# coding: utf-8
# Example code to read the extended AMeDAS WEA2 file.
# author     Yuichi Yasuda @ quattro corporate design
# copyright  2024 quattro corporate design. All right reserved.

import numpy as np
import pandas as pd
import math
import os

# WEA2 File path
WEA2_FILE = r"E:\EAD\PRY1120.wea2" 
BLOCK_NO = 363  # Station number, Tokyo(3630)
# BLOCK_NO = 444  # Station number, Irozaki(4440)

# Constants
RECORD_LENGTH = 18306  # Length of one record in bytes
NUM_RECORDS = 11       # Number of records
BLOCK_LENGTH = RECORD_LENGTH * NUM_RECORDS  # Data size for one location in bytes
TOTAL_LENGTH = RECORD_LENGTH * 10  # Actual data size excluding the first location record in bytes
NVALS = int(TOTAL_LENGTH / 2)  # Number of int16 values

# Check if file exists
if not os.path.exists(WEA2_FILE):
    raise FileNotFoundError(f"The file {WEA2_FILE} does not exist.")

try:
    # Read binary file
    with open(WEA2_FILE, "rb") as f:
        # Move to the start position of the target location
        f.seek(BLOCK_LENGTH * (BLOCK_NO-1))
        # Skip the first record ([0]location information)
        f.seek(RECORD_LENGTH, 1)
        # Read data for [1]temperature to [10]relative humidity
        data = np.fromfile(f, dtype=np.int16, count=NVALS)
except Exception as e:
    raise IOError(f"An error occurred while reading the file: {e}")

# Reshape data to DataFrame(10 records x 9153 x int16)
data = data.reshape((10, 3 + 366 * 24 + 366))
df = pd.DataFrame(data)

# Remove the first 3 columns (location number, type, year)
df = df.iloc[:, 3:]
# Extract the first 365*24 columns, excluding the 366-day daily averages
df = df.iloc[:, :365 * 24]

# Reset the column numbers of the dataframe from 0 to 8759
df.columns = range(8760)

# Remove the remark (Remove the first digit of the value)
# Divide all values in df by 10 using math.floor()
df = df.applymap(lambda x: math.floor(x / 10))

# Transpose the rows and columns of df
df = df.T

# Correspondence between values and units
#  Temperature, Absolute Humidity, Global Solar Radiation, Atmospheric Radiation, Wind Direction, Wind Speed, Precipitation, Sunshine Duration, Local Pressure, Relative Humidity
#  0.1degC,    0.1g/kg,           0.01MJ,                0.01MJ,                16 directions,  0.1m/s,     0.1mm,        0.01h,              hPa,            0.1%

# Unit conversion factors and conversion of df units
unitf = [0.1, 0.1, 0.01, 0.01, 1.0, 0.1, 1.0, 0.01, 1.0, 0.1]
df = df * unitf
labels = ["Temperature[C]", "Absolute Humidity[g/kg]", "Global Solar Radiation[MJ]", "Atmospheric Radiation[MJ]", "Wind Direction[-]", "Wind Speed[m/s]", "Precipitation[mm]", "Sunshine Duration[h]", "Local Pressure[hPa]", "Relative Humidity[%]"]
df.columns = labels
# Write df to a CSV file
df.to_csv(f"EA_{BLOCK_NO}.csv", index=False, header=True)

出力例

図はCSVをExcelで開いた例です。各列ごとに値が時系列で出力されます。サクッと確認した感じ正しい値が出力されていると思います。試される方はDataNavi8の出力と比べてからご利用ください。

なにか、不具合などあればコメントください。

動作環境

以下の環境で動作を確認しています。

  • Windows11 Pro(64bit, 24H2)
  • Python 3.12.4
  • 標準年EA気象データ2020年版(WEA2)
Pocket

コメントする

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