お世話になります。
rubyのプログラムを組んだのですが、出力に時間がかかるため、どうにか高速化できないかという相談です。
rubyを使用して
acc_x.csv acc_y.csv acc.z.csv
という3つの数値解析ファイルから列ごとにテキストファイルを出力させたいと思っております。
それぞれのファイルを一部抽出したものを以下に記載させて頂きます。
acc_x.csv
time,1,2,5,10,13
0.01,0.785958008,-0.274499466,-0.04875417,0.277856228,-0.166021321
0.02,0.500327211,-0.061038414,0.580773155,0.397613981,0.260582952
0.03,-0.108020639,-0.273086752,0.160661689,0.241324649,0.028759969
0.04,0.310627648,0.001429172,0.091403594,-0.305568004,0.826153173
0.05,-0.257493861,-0.475250007,0.186605183,0.031059334,0.845045269
0.06,0.163644999,-0.384227085,-0.165840021,0.275938253,0.644296185
0.07,0.055154002,-0.568280995,0.184234876,-0.572951645,0.102156244
0.08,-0.350023989,-0.11692816,0.262549184,0.293178365,0.439308897
0.09,-0.091233971,-0.184686171,0.755416196,0.18408131,0.67840418
0.1,-0.220665702,0.395159564,-0.076555628,-0.283248903,-0.117443896
acc_y.csv
time,1,2,5,10,13
0.01,-0.595558906,0.07294466,-0.106053852,-0.041407645,0.78285035
0.02,-0.2567976,-0.352352662,0.449620458,-0.572029331,-0.519173866
0.03,0.37704531,-0.338795392,0.025760981,-0.890864656,-0.01955793
0.04,-0.711042009,-0.055702349,0.658077034,0.342903809,0.203497863
0.05,0.656198235,-0.243704778,0.345243588,0.224393765,-0.542427698
0.06,-0.544045512,-0.692627935,-0.58506749,-0.317839259,0.313767218
0.07,0.458234249,-0.339504431,0.35664675,-0.653384157,-0.09970446
0.08,-0.001167412,-0.254440685,-0.850123892,0.373257703,-0.540415036
0.09,-0.661368491,-0.080536849,-0.320307516,0.286827238,0.658116411
0.1,0.161428938,-0.328336073,0.10393651,-0.320717467,-0.556967052
acc_z.csv
time,1,2,5,10,13
0.01,0.124781351,0.139025231,-0.249542182,0.250675217,-0.261333158
0.02,0.058236711,0.788391173,-0.045054373,0.913832437,-0.520917922
0.03,-0.425799344,0.06491633,-0.220356549,0.010808446,-0.012345955
0.04,-0.106479085,0.069571527,-0.819504969,-0.680273688,-0.476894582
0.05,-0.028521568,0.481298624,0.211427059,-0.406888097,-0.348843099
0.06,-0.1131719,0.397351719,0.23308442,-0.042568532,0.201701772
0.07,0.58261087,0.169149533,0.412807036,0.073169201,0.948218341
0.08,-0.321402494,0.261607689,-0.113240059,-0.564063202,-0.134732901
0.09,-0.097148189,0.60216685,0.177890054,0.168810598,-0.014560554
0.1,-0.377921037,0.492026522,-0.791015033,0.759523057,0.56215856
上記のファイルの一行目の1,2,5,10,13というのは地点名称であり一列目は観測時間であります。
列ごとの観測結果の単位がm/s2であり、必要なのはcm/s2という単位系なので、観測結果の値を100倍してやり
それぞれの地点ごとに
acc_1.dat
acc_2.dat
acc_5.dat
のようなテキストファイルで保存したいと思っております。
結果のイメージは
acc_1.dat
time X_acc(gal) Y_acc(gal) Z_acc(gal)
0.01 7.8596e+01 -5.9556e+01 1.2478e+01
0.02 5.0033e+01 -2.5680e+01 5.8237e+00
0.03 -1.0802e+01 3.7705e+01 -4.2580e+01
0.04 3.1063e+01 -7.1104e+01 -1.0648e+01
0.05 -2.5749e+01 6.5620e+01 -2.8522e+00
0.06 1.6364e+01 -5.4405e+01 -1.1317e+01
0.07 5.5154e+00 4.5823e+01 5.8261e+01
0.08 -3.5002e+01 -1.1674e-01 -3.2140e+01
0.09 -9.1234e+00 -6.6137e+01 -9.7148e+00
0.1 -2.2067e+01 1.6143e+01 -3.7792e+01
のようなものであります。
上記の仕様を一応は満足できるようにrubyを使って組んでみました。
ruby
1# coding: cp932 2Encoding.default_external=__ENCODING__ 3Encoding.default_internal=__ENCODING__ 4Ix=IO.readlines("acc_x.csv",chomp:true) 5Iy=IO.readlines("acc_y.csv",chomp:true) 6Iz=IO.readlines("acc_z.csv",chomp:true) 7comma="," 8tab="\t" 9str="%.4e" 10h=1 #地点名称存在行 11r=5 #繰り返し回数(row) 12tx=ty=tz=100 #係数倍_mからcm/s2への変換 13input=[] #いつもながらなぜか必要な物。なぜ必要なのかよく分かってません。 14r.times{|n| #繰り返し 15 x=n+1 #一列目が時刻歴だから+1しておく 16 y=x+r+1 #acc_xファイルの後にacc_yを追加する。一列目は時刻歴だから+1しておく 17 z=y+r+1 #acc_yファイルの後にacc_zを追加する。一列目は時刻歴だから+1しておく 18 s=[Ix[h-1],Iy[h-1],Iz[h-1]].map{|a| #地点名以下を選択する。その配列はaとする 19 a.split(comma)}.flatten #コンマ区切りのファイルだからコンマで分割。 20 input<<(outputfile="acc_%s.dat"%s[x]) #acc_xファイルの地点名をファイルに付加。やっぱりinput<<がいる。何をしているのだろう? 21 22 open(outputfile,"wt"){|b| #ファイル書き込み処理。変数はbとする。 23 b.puts ["time","X_acc(gal)","Y_acc(gal)","Z_acc(gal)"].join(tab) #変数bのファイルにヘッダーを付ける。 24 (h...Ix.size).each{|c| #行数取得 25 s=[Ix[c],Iy[c],Iz[c]].map{|e| #行数分の数値を入手する 26 e.split(comma).map(&:to_f)}.flatten 27 b.puts [s[0],str%(tx*s[x]),str%(ty*s[y]),str%(tz*s[z])].join(tab) #係数倍をしてコンマ4桁で出力してタブ区切り 28} } } 29input.each{|n| 30 puts n #列数分繰り返し 31 puts IO.readlines(n,chomp:true) 32}
上記のようにプログラムを組んだところ、どうにか出力までは漕ぎつけられました。
今回の例題のようなわずかな行列数ではすぐに出力が終わるのですが、それが6000列×12000行という莫大な数になると、終了まで8時間以上かかってしまいました。
何とか早くしたいのですが、私ではこれ以上何ともなりませんでした。
上記プログラムには、自分の理解していることをメモとして残してあるのですが、覚え違いなどがあればそれもぜひご指摘お願いいたします。
それと、現在は0.0000e+00となっているのですが、できれば0.0000e+000の形式で表せれたらとも思っています。
組んだプログラムとテストファイルを置いてある外部サイトも掲載しておきます。
よろしくお願いします。
リンク内容
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/02/21 15:26
2018/02/21 15:38
2018/02/21 15:52
2018/02/21 23:22
2018/02/22 00:35
2018/02/22 03:30
2018/02/22 03:32
2018/02/22 04:13