気象庁の二酸化炭素濃度データ

気象庁の「世界の年平均気温偏差」データがときどき読めなくなる(CSVファイルとしてまずくなる)話の関連である。

気象庁の二酸化炭素濃度の経年変化のページでは,岩手県大船渡市三陸町綾里(りょうり)東京都小笠原村南鳥島(みなみとりしま)与那国島(よなぐにじま)(沖縄県八重山郡与那国町)で二酸化炭素濃度の観測をしている。

例えば綾里のCSVは次のような形式である:

年,月,二酸化炭素濃度の月平均値(綾里)[ppm],
1987, 1,353.2,
1987, 2,354.0,
1987, 3,354.8,
(中略)
2021, 4,424.3,)
2021, 5,423.5,)
2021, 6,416.7,)

 --印は、機器の異常等による欠測を表しています。
 ) が付いたデータは速報値です。

 気象庁ホームページのコンテンツのご利用については以下のWebサイトをご覧ください。
 (https://www.jma.go.jp/jma/kishou/info/coment.html)

このように,データの後ろに不定行数のコメントが付いている。この部分を何とかしないとデータとして自動処理できない。

この場合,4列のデータのうち「年」「月」は欠測値がないことを使えば次のようにして読める:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv("co2_monthave_ryo.csv",
                 encoding="cp932", na_values=["--"]).dropna(thresh=2)
t = [pd.to_datetime(f"{x['年']}-{x['月']:02.0f}-15") for i, x in df.iterrows()]
plt.plot(t, df.iloc[:, 2])
綾里の二酸化炭素濃度

ただ,欠測値の個数で調べる方法は,データの中に最初の1列以外すべて欠測値の行があったらうまくいかない。

もう一つ,良い手段を教えていただいた。Split Pandas DataFrame on Blank rows を使って空行でデータフレームを分割する:

import numpy as np

df = pd.read_csv("co2_monthave_ryo.csv",
                 encoding="cp932", na_values=["--"], skip_blank_lines=False)
df_list = np.split(df, df[df.isnull().all(1)].index)

これで df_list[0] にデータが入る。df_list[1] 以下には末尾のコメントが入る。

さらに別の方法を教えていただいた:

df0 = pd.read_csv(url, encoding="cp932", dtype=str, na_values=["--"])
df1 = df0[df0["年"].str.strip().str.isnumeric() & df["月"].str.strip().str.isnumeric()]

この場合は次でもいいかも:

df = pd.read_csv(url, encoding="cp932", na_values=["--"])
df = df[df["年"].str.isnumeric()]

よく見ると,コメントがスペースで始まっているので,pd.read_csv(..., comment=" ") でいけるかと思ったら,1桁の月の前にもスペースがあるので,うまくいかない。ところが,これも教えていただいたのだが,skipinitialspace=True とするとコンマの後のスペースだけ読み飛ばす(行頭のスペースは読み飛ばさない)ので,これらを組み合わせればうまくいく:

df = pd.read_csv(url, encoding="cp932", na_values=["--"],
                 skipinitialspace=True, comment=" ")

しかも,この場合はコメントを読んでから捨てるのではなく最初から読まないので,「年」も「月」も型は自動で int64 になる。

(そもそもコメントには頭に # を付けてほしい。)

R版も書いた。


Last modified: