ホーム > matplotlibの使い方 > 気象データ処理のTIPS

matplotlib:気象データ処理のTIPS


作成者:山下陽介(国立環境研究所)



目次

[top]



CSVファイル

CSVファイルの形式

CSV(Comma-Separated Values)は、カンマ区切りのテキストデータ
時刻,項目1,項目2,項目3
時刻1,データ1-1,データ1-2,データ1-3
時刻2,データ2-1,データ2-2,データ2-3
...
ヘッダがない場合を扱うことも可能

CSVファイルの読み込み

pandasのread_csvを用いる方法
import pandas as pd
df = pd.read_csv("ファイル名")
*読み込み時にUnicodeDecodeErrorが出る場合は、CSVファイル読み込み時のエラー参照

CSVファイルの時刻処理

CSVファイルの行処理

CSVファイルの時刻がparse_dates未対応の場合

日付データへの変換処理をdate_parserに関数で指定
import pandas as pd
df = pd.read_csv("ファイル名", parse_dates=[0], index_col=[0], date_parser=parse_dates)
parse_datesが関数名

CSVファイルの列処理

CSVファイルとして書き出す

pandasのDataFrameを使う場合

CSVデータの文字列を数値に変換する

文字列のまま一度書き出し、再読み込みを行うと数値データに変換される

CSVファイル読み込み時のエラー

読み込み時にUnicodeDecodeErrorが出る場合(UTF-8でない場合には、文字化けではなくエラーとなる)
df = pd.read_csv("ファイル名", encoding='shift_jis')
*WindowsのShift JISで読み込む

圧縮されたCSVファイルの読み込み

pd.read_csvのcompressionオプションは、デフォルトで'infer'なので、ファイルの拡張子を見て圧縮ファイルかどうか判断してくれる
df = pd.read_csv("ファイル名")
具体的に圧縮形式を指定する場合、 pd.read_csvにcompressionオプションを付ける。
df = pd.read_csv("ファイル名", compression="bz2")
*bz2で圧縮されたCSVファイルを読み込む

CSVファイルを圧縮して書き出し

pandasのDataFrameの書き出しの際にcompressionオプションを付ける
df.to_csv("ファイル名.gz", compression='gzip')
*gzipで圧縮したCSVファイルを書き出す

TSVファイル

TSVファイルの形式

TSV(Tab-Separated Values)は、タブ区切りのテキストデータ
時刻<tab>項目<tab>項目2<tab>項目3
時刻1<tab>データ1-1<tab>データ1-2<tab>データ1-3
時刻2<tab>データ2-1<tab>データ2-2<tab>データ2-3
...
*<tab>は制御文字のHT(Horizontal Tabulation:水平タブ)を表す

TSVファイルの読み込み

pandasのread_csvにsepオプションを与える *読み込み時にUnicodeDecodeErrorが出る場合は、CSVファイル読み込み時のエラー参照

TSVファイルとして書き出す

pandasのDataFrameを使う場合

LTSVファイル

TSVファイルの中には、Labeled Tab-separated Values(LTSV)形式のものがある 。各列にラベルを付けることで、データが欠損になった場合やデータが追加になった場合にも柔軟に対応できる。

SSVファイル

SSVファイルの形式

SSV(Space-Separated Values)は、スペース区切りのテキストデータ
時刻  項目  項目2  項目3
時刻1  データ1-1  データ1-2  データ1-3
時刻2  データ2-1  データ2-2  データ2-3
...

SSVファイルの読み込み

pandasのread_csvにsepオプションを与える *読み込み時にUnicodeDecodeErrorが出る場合は、CSVファイル読み込み時のエラー参照

SSVファイルとして書き出す

pandasのDataFrameを使う場合

JSONファイル

JSONファイルの形式

データの名前(キー)とデータの組み合わせを決められたフォーマットで記述し、階層構造を持たせたテキストデータ
{"時刻1":{
    {"キー1":"データ1"},
    {"キー2":"データ2"},
    {"キー3":["データ3-1","データ3-2","データ3-3"]},
    ...},
"時刻2":{
    {"キー1":"データ1"},
    {"キー2":"データ2"},
    {"キー3":["データ3-1","データ3-2","データ3-3"]},
    ...},
...
}
*時刻毎に複数のデータが入っている場合

JSONファイルの読み込み

JSONファイルの書き出し

jsonモジュールを使う
import json
d = ...
with open('ファイル名', 'w') as fout:
    json.dump(d, fout)
df = pd.DataFrame(json.loads(data))
データの形式については、JSONファイルの形式参照

バイナリファイル

バイナリファイルの形式

ここでは、GrADS等で用いられる下記の形式の単純なバイナリファイルについて記載している。NumPy独自のバイナリ(npy、npz)とは異なる。
4バイト浮動小数点数(単精度)のデータや8バイト浮動小数点数(倍精度)のデータを改行コード無しで並べた単純バイナリ形式

バイナリファイルのエンディアン

エンディアン:2バイト以上のデータを保存する場合の保存順序の規則
ビックエンディアン(Big Endian)とリトルエンディアン(Little endian)の2種類

バイナリファイルの読み込み

バイナリファイルの書き出し

Numpy独自のバイナリファイル

Numpy独自のバイナリファイルの形式

Numpyでは、内部で使われている配列ndarrayをNumpy独自のバイナリファイル(npy、npz)として保存できる。配列のデータ型や形状を保持でき、npyでは1つの配列、npzでは複数の配列を保存できる。このバイナリ形式はNumpy独自であり機種依存性もあるため、基本的には同じマシンでNumpyを利用して読み書きを行う。

Numpy独自のバイナリファイルの読み書き

モジュールをインポートする
import numpy as np

NetCDFファイル

NetCDFファイルの形式

NetCDFファイルには、データと一緒に格子点の情報やデータの説明も一緒に格納されている。データの説明も格納できるため、データを作成したモデルの名前や作成者、変数の導出方法、参照元の文献やURL などを記述しておけば、利用者がデータの中身を理解しやすい。また、格納されたデータを機種に依存することなく取り出せるため、データの配布に適している。

NetCDFのモジュール

モジュールをインポートする
import netCDF4

インポートでエラーが出る場合

NetCDFファイルの読み込み

NetCDFファイルに含まれている変数名などを確認する
% ncdump -h ファイル名
ファイルを開き、指定した変数名のデータを取り出す
nc = netCDF4.Dataset('ファイル名', 'r')
var = nc.variables['変数名'][:]

NetCDFファイル情報の取得

nc = netCDF4.Dataset('ファイル名', 'r')
idim = len(nc.dimensions['lon']) # 経度方向のデータ数
jdim = len(nc.dimensions['lat']) # 緯度方向のデータ数
ndim = len(nc.dimensions['time']) # 時間方向のデータ数
add_offset = nc.variables['変数名'].add_offset # データのオフセット
scale_factor = nc.variables['変数名'].scale_factor # データのスケールファクター

データにスケールファクターとオフセットがある場合

nc = netCDF4.Dataset('ファイル名', 'r')
var_i = nc.variables['変数名'][:]
add_offset = nc.variables['変数名'].add_offset
scale_factor = nc.variables['変数名'].scale_factor
var = var_i * scale_factor + add_offset

変数がグループ化されている場合

グループ化されている場合、
% ncdump -h ファイル名
でvariablesの上位にgroupが表示される。その場合、groupの下位に表示される変数名(ここでは変数名1、変数名2があるものとする)を使い、以下のように取り出す
nc = netCDF4.Dataset('ファイル名', 'r')
grp = nc.groups['グループ名']
var1 = grp.variables['変数名1'][:]
var2 = grp.variables['変数名2'][:]

GRIB2ファイル

GRIB2ファイルの形式

WMOが定めたバイナリデータの交換形式のうち、2001年に制定された第2版を指す。後述のGRIB1形式とは互換性がない。格納されたデータを機種に依存することなく取り出すことができ、データと一緒に格子点の情報や変数の簡単な説明等も格納できる。詳細についてはQiitaの記事に詳しい。

GRIB2ファイルの読み込み

GRIB2ファイルの読み込みを行うには、まずGRIB2からNetCDFへ変換し、NetCDFとして読み込む方法が良い。変換にはwgrib2を用いる。MacPortsであれば、
% sudo port install wgrib2
で導入できる。wgrib2を用いて次のように変換する。
% wgrib2 入力ファイル名 -netcdf 出力ファイル名
変換後のファイルは、NetCDFに記述した方法で読み込み可能
*wgrib2のバージョン3.1.2ではJPEG2000のエラーが発生するデータが存在する。バージョン3.1.3では解消された。

pygribを使ったGRIB2ファイルの読み込み

pygribモジュールを用いると、直接GRIB2ファイルを読み込むことができた。
% sudo port install py310-pygrib
で導入できる(python3.10の場合。異なるバージョンではpy310の部分を変える)。pygribでは次のようにデータを取り出す。
import pygrib
grbs = pygrib.open("ファイル名") # GRIB2ファイルを開く
grb1 = grbs.select(forecastTime=1)[0] # 1時間後の0番目の変数
grbt = grbs.select(name="Temperature") # 気温の変数を選択
ファイルの読み込みに時間がかかるため、読み込み処理が多い場合にはGRIB2ファイルの読み込みに記述した方法に切り替えた方が良い。
*MacPortsでは、python3.11以降のpygribが提供されていない。

wgrib2による単純バイナリファイルへの変換

wgrib2コマンドを使うと、単純バイナリファイルに変換可能。変換したファイルの読み込み方法はバイナリファイルの読み込み参照。北極が先、下層が先に入ったビックエンディアンの単純バイナリファイルに変換する場合
% wgrib2 -v 入力ファイル.grb | grep "変数名" | grep "時刻" | sort -nr -k5 -t':' \
  | wgrib2 入力ファイル.grb -i -no_header -order we:ns -ieee -o 出力ファイル.bin
*-no_headerはヘッダ無し、-ieeeはビックエンディアン
*-order we:nsで、西から東、北から南の順に並べ替えて出力
*下層が先になるように、sort -nr -k5 -t':'で並べ替えを行っている
*最初のwgrib2は、ファイルの中に含まれる変数をリスト化するためのもので、2回目のwgrib2は、リストを読み込んで入力ファイルからリストに対応するデータをファイルに書き出すためのもの。grepやsortでリストのうち必要な変数の取り出しや並べ替えを行う。
*追加書き込みを行う際には、wgrib2 入力ファイル.grb -i -no_header -append -order we:ns -ieee -o 出力ファイル.bin

GRIB1ファイル

GRIB1ファイルの形式

WMOが定めたバイナリデータの交換形式のうち、1989年に制定された第1版を指す。前述のGRIB2形式とは互換性がない。格納されたデータを機種に依存することなく取り出せ、データと一緒に格子点の情報や変数の簡単な説明等も格納できる。

GRIB1ファイルの読み込み

GRIB1形式は、pythonで直接読むことはできないが、GrADSに付属しているwgribコマンドを使うことで、単純バイナリファイルに変換可能。変換したファイルの読み込み方法はバイナリファイルの読み込み参照。JRA-55客観解析データの気圧面データを使い、下層が先に入ったビックエンディアンの単純バイナリファイルに変換する場合
% wgrib -v 入力ファイル.grb | grep ":GRIBIDを記述," | sort -nr -k5 -t':' \
  | wgrib -i -nh -ieee 入力ファイル.grb -o 出力ファイル.bin
*-nhはヘッダ無し、-ieeeはビックエンディアン
*下層が先になるように、sort -nr -k5 -t':'で並べ替えを行っている
*最初のwgribは、ファイルの中に含まれる変数をリスト化するためのもので、2回目のwgribは、リストを読み込んで入力ファイルからリストに対応するデータをファイルに書き出すためのもの。grepやsortでリストのうち必要な変数の取り出しや並べ替えを行う。
*追加書き込みを行う際には、wgrib -i -nh -ieee -append 入力ファイル.grb 出力ファイル.bin

HDF5ファイル

HDF5ファイルの形式

HDF形式は、米国立スーパーコンピュータ応用研究所(National Center for Supercomputing Applications:NCSA)で開発され、大量のデータを格納し構造化するために設計されている。データと一緒に格子点の情報や変数の説明なども格納することができ、格納されたデータを機種に依存することなく取り出せる。HDF形式には、古いHDF4形式と新しいHDF5形式があり、両者に互換性はない。HDF5はファイル構造が単純化されており、ディレクトリに相当するグループとファイルに相当するデータセットの2種類で階層構造を持って保存することができる。

HDF5ファイルの読み込み

Pythonでは、Pandasやh5pyでHDF5ファイルを読むことができる。Pandasで読み込めない形式の場合にはh5pyを使う。

GTOOL3ファイル

GTOOL3ファイルの形式

GTOOL3形式は、気候モデルMIROCの出力に用いられているバイナリ形式で、ヘッダ部とデータ部のセットで構成され改行コードで区切られている。ヘッダ部にはデータ部の格納形式(例えば、1レコードが4バイトか8バイトか)やサイズ、欠損値、日時などが16 文字×64欄の文字データとして格納されている。また、データの経度、緯度、高度方向の格子点数や、格子点値が記述された格子情報ファイル名なども格納され、データの名前、作成 、作成日時なども記述することができる。データ部は単純バイナリで、ビックエンディアン、リトルエンディアンどちらも許容されており、機種依存性がある。

GTOOL3ファイルの読み込み

GTOOL3の読み込みには、gtool3更新版を用いることができる。
from gtool3 import gtopen
gt = gtopen("ファイル名") # GTOOL3ファイルを開く
d = gt['変数名'][:, :, :, :] # 変数名に対応するデータ取得(次元はデータに合わせる)
*時刻、高度、緯度、経度が入ったデータの場合
*変数名や次元はgt.varsで表示できる。
*気候モデルのMIROCの出力を用いた処理方法は、PythonでGTOOL3ファイルを処理するに詳しい。

画像ファイル

画像ファイルの読み込み(Pillow)

ここでは、様々な画像フォーマットに対応しているPillowを利用した読み込み方法を紹介する。Pillowでは、PNG、BMP、GIF、JPEG、TIFF、EPSなど、主要な形式の読み書きに対応している。読み込む場合には、
from PIL import Image
im = Image.open("画像ファイルのパス")
Numpyで扱う場合には、次のようにndarrayに変換する
im = np.asarray(im)
urllibを利用して、web上の画像を読み込むことも可能
from PIL import Image
import urllib.request
im = Image.open(urllib.request.urlopen("URLを指定"))

画像ファイルの書き出し(Pillow)

Pillowで書き出す場合には、
im.save("画像ファイル名")
書き出す画像の質を指定する場合(jpg)、
im.save("画像ファイル名.jpg", quality=95)

読み込んだ画像の処理(Pillow)

Pillowの機能としてグレースケール変換、切り出し、サイズの変更などが可能。
[top]