「Python で簡単なテキスト処理 (1) - 特定の単語が含む行を抽出する」の続き。
1. 表から、特定の列を抽出したい
今回は、実際に存在するデータから、特定の列を抽出をしてみる。
抽出対象のデータは、気象庁で公表されている気象データ。
気象庁 | 日ごとの値 via kwout
気象庁の過去のデータを見ると、日毎、時間毎に、いくつかの観測対象のデータが載せられている。
上記のデータは、
「 2008 年 1 月の東京の日ごと」
の気象データが掲載されているページ。この中から、特定の観測対象のデータのみを抽出したい。ただし、抽出するとき、抽出データを後で表計算に貼り付けるため、「タブ区切り」にすること。
対象の項目は、「現地の気圧」と「平均気温」のとする。
2. データをブラウザからエディタに貼りつける
例えば、東京の2008/1/1 ~ 1/5 までのデータを、ブラウザ上で選択し、エディタに貼り付けると、次のようになる。
1 998.7 1003.1 -- -- -- 6.0 10.9 1.8 36 16 2.6 4.8 北西 9.4 北西 6.9 -- -- 晴後一時曇 快晴 2 1007.2 1011.7 -- -- -- 6.2 11.2 1.1 35 19 3.1 6.6 北西 13.3 北西 9.1 -- -- 快晴 快晴 3 1011.6 1016.1 -- -- -- 5.9 10.4 1.5 45 29 1.8 3.6 北北西 6.4 南南東 9.1 -- -- 晴 快晴 4 1014.6 1019.1 -- -- -- 7.0 12.1 2.7 43 24 2.5 5.0 北西 9.4 北北西 9.0 -- -- 快晴 晴後曇 5 1014.0 1018.6 0.0 0.0 0.0 6.0 8.7 4.0 53 39 2.0 3.8 北西 6.1 西北西 3.7 --
これを文字列として変数に代入し、処理をする。
3. Python の場合
data = ur"""ここに上記のデータを貼り付ける"""
import re
# 改行でデータを分割
for line in data.split('\n'):
# 日付の行は飛ばす
if re.search('^\d{1,2}$', line): continue
# 空白でレコードを分割
rec = line.split()
# 必要な観測データのみ、タブ区切りでレコードを出力
print rec[0], '\t', rec[5]
以下を参考。
リスト内包表記を使う場合
追記(2008.6.10): リスト内包表記を利用し、後述する Ruby のコードを真似てみる。
data = ur"""ここにデータを貼り付ける"""
for line in [line for line in
data.split('\n') if not re.search('^\d{1,2}$', line)]:
for i,v in enumerate(line.split()):
if i == 0: print v, "\t",
elif i == 5: print v
うーん、読みにくい... ^^;
enumerate() をリスト内包表記の中に入れてやれば、
data = ur"""ここにデータを貼り付ける"""
for a,b in [filter(lambda (i,v): i in [0, 5] , enumerate(line.split()))
for line in
data.split('\n') if not re.search('^\d{1,2}$', line)]:
print a[1], "\t", b[1]
filter() をリスト内包表記に変更すると、
data = ur"""ここにデータを貼り付ける"""
for rec in [[v for i,v in enumerate(line.split()) if i in [0,5]]
for line in
data.split('\n') if not re.search('^\d{1,2}$', line)]:
print rec[0], "\t", rec[1]
enumerate() した後にフィルタしたものを [] で囲むのを忘れずに。
ついでに、reduce() を使うなら、(参考: jijixi's diary - リストの扱いあれこれ)
data = ur"""ここにデータを貼り付ける"""
for rec in [reduce(lambda r,(i,v): r + [v] if i in [0,5] else r,
enumerate(line.split()),
[])
for line in
data.split('\n') if not re.search('^\d{1,2}$', line)]:
print rec[0], "\t", rec[1]
reduce() 内の lambda における v を [] で囲むのを忘れずに。
しかし、慣れていないので読みにくい... ^^;
4. Ruby の場合
Ruby の場合、正規表現の書き方がシンプルでいい ^^
DATA.each do |line|
next if line =~ /^\d{1,2}$/
rec = line.split
print rec[0], "\t", rec[5],"\n"
end
__END__
ここにデータを貼り付ける
追記(2008.6.10): 最初に不必要なデータを削除しておくやり方。
DATA.reject{|line|
line =~ /^\d{1,2}$/
}.each{|line|
line.split.each_with_index{|v,i|
case i
when 0
print v, "\t"
when 5
puts v
end
}
}
__END__
ここにデータを貼り付ける
6. 関連記事
- → Haskell で簡単なテキスト処理 - データの抽出
- Firefox でウェブサイトの表の内容をコピーして表計算ソフトに貼り付ける
- Google スプレッドシートで HTML の table 要素を抽出 – ImportHtml 関数
- 気象庁の過去のデータを開くためのブックマークレット
0コメント:
コメントを投稿