「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コメント:
コメントを投稿