[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dennou-ruby:003054] Re: Fw: 電脳Rubyで2次元gribファイル読み込み



堀之内です.

栗田さんの質問の後半について.

> さて、ここで質問があるのですが、このファイルでは、66行目から
> 72行目のところで、3次元データ(value)を読み込ん 
> で、時間軸を加え
> た4次元データ(array)を出力しているのですが、どう 
> やってもRuby
> らしく書くことができませんでした。Gphysの機能を使って、 
> もっと
> スマートに書けると思いますが、堀之内さんならどのようにされま
> すか?向学の為にご助言頂ければ幸いです。

もとのソースは

       for k in 0...z.length do
       for m in 0...y.length do
       for l in 0...x.length do
           array[l,m,k,i-1] = value[l,m,k]
       end
       end
       end

ですね.こうやって,ruby レベルでループをまわすと遅くなりますので,
次のようにします.

       array[true,true,true,i-1] = value

trueは指定された次元の全選択です.value は全部を代入するので,
わざわざ value[true,true,true] とする必要はないです.
なお,任意個の次元の全選択 (yorick でいう rubber 次元)を
false であらわせますので,こうも書けます:

       array[false,i-1] = value

これだと,value の次元より array の次元が一つ大きさえ
すれば,両者が何次元でも大丈夫ですので,例えば
地表データと多層の気圧面データの両方に使えるプログラムが
かけます.(なのでお勧め)

以上はNArrayの機能ですが,GPhys (やその下のVArray) でも
同じように使えるようにしてあります.NArray で
なくても,「数値配列のようなもの」であればなるべく
同じメソッドが使えるようにしてあるというわけです.

さて,ついでに他もちょっとみてみました.標準添付ライブラリ
の date を使うとかなり楽になります.

require "date"

とプログラムの冒頭に書くと使えるようになります(冒頭
でなくてもいいですが).ファイル中に,

yr      = 2004
fname   = 'tmp'

jend = yymmdd_to_ddd( yr, 12, 31 )

for i in 1...jend do
    mo,dy = yyddd_to_mmdd( yr, i )
    yy = sprintf("%2.2d",yr)
    mm = sprintf("%2.2d",mo)
    dd = sprintf("%2.2d",dy)
    file = fname + yy + mm + dd + "00.grib"

となってる部分があって,yymmdd_to_ddd や yyddd_to_mmdd
を別途定義してますが,次のようにすると,関数定義不要です.

# バグあったらすみません.

yr      = 2004
fname   = 'tmp'

day1 = Date.new(yr,1,1)
nd = ( Date.new(yr+1,1,1) - day1 ).to_i

for i in 0...nd do
  date = day1 + i
  file = date.strftime("#{fname}%y%m%d00.grib")