アプリ版:「スタンプのみでお礼する」機能のリリースについて

pythonまたはrubyを用いた複数ファイル間での計算方法を知りたいです。
pythonはバージョン3
ruby2.5
がインストールされているWINDOWS7_64bitです。

現在、X.csv Y.csv Z.csvという3ファイルがあります。そのファイルにはそれぞれの地点での速度のデータが入っています。それらの3ファイルから合成速度を出すための方法が知りたいです。数が少ない場合には表計算ソフトでできるのですが、データ数が多くなると表計算ソフトに展開後計算でフリーズが多発するようになってしまいました。(ファイルは一つ当たり重たい場合で300MB程度になります。)

ファイルの一行目には観測地点名
ファイルの一列目には観測時刻が入っています。
以下にダミーファイルですが内容を記載します。

X.csvファイル
_______
観測点↓_時刻→,0.01,0.02,0.03
1,0.974286674,0.522857461,0.536415555
2,0.799521755,0.066823814,0.001082381
3,0.699774803,0.268318804,0.902615533
4,0.984650621,0.084935095,0.179747532
5,0.218257008,0.905444955,0.436724953
_______

Y.csvファイル
_______
観測点↓_時刻→,0.01,0.02,0.03
1,0.708681792,0.781146942,0.462420352
2,0.799182472,0.332490182,0.307522361
3,0.219630189,0.432992572,0.85617064
4,0.593084967,0.66612698,0.751198143
5,0.842517186,0.381417077,0.908781172
_______

Z.csv
_______
観測点↓_時刻→,0.01,0.02,0.03
1,0.215413351,0.504188048,1.395553793
2,0.957916818,1.468535607,0.175732259
3,1.719424373,0.283856812,0.839045408
4,1.655414076,0.231217526,1.17794877
5,0.723389776,0.176750832,1.282434654
_______

上記のような3ファイルを
SQRT(X^2+Y^2+Z^2)
で計算した結果を合成結果.csvとして出力させたいです。

たとえば観測点1で時刻0.01の時であると
SQRT(X^2+Y^2+Z^2)
=sqrt(0.974286674^2+0.708681792^2+0.215413351^2)
=1.223873898
のようになります。

合成結果
_______
観測点↓_時刻→,0.01,0.02,0.03
1,1.223873898,1.06666586,1.564974319
2,1.481732867,1.507186774,0.354193451
3,1.869316016,0.583139981,1.500579942
4,2.015361602,0.710211707,1.408606095
5,1.131708486,0.998273715,1.631333977
_______


一つのファイル内で
観測点↓_時刻0.01,X,Y,Z
1,X速度,Y速度,Z速度
2,X速度,Y速度,Z速度
.
.
観測点↓_時刻0.02,X,Y,Z
.
.
観測点↓_時刻0.03,X,Y,Z
.
.

のような形式ならようやくrubyで計算できるようになったのですが、複数ファイルの取り扱い方法がまだわかっていない状況です。お分かりになる方がお見えでしたらぜひとも教えてください。

A 回答 (2件)

rubyです。

以下のスクリプトを実行してください。
合成結果.csvに出力されます。
計算結果は提示サンプルに合わせて小数点以下9桁にしています。
桁数の調整は
vstr = sprintf("%.9f",v)
で行ってください。
vstr = v.to_s
で単純に文字列にすると、もっと長い桁数になります。
尚、以下の前提で作成しています。
X.csv,Y.csv,Z.csvの行数は全て同じであること。
X.csv,Y.csv,Z.csvの列数も全て同じであること。
X.csv,Y.csv,Z.csvの観測点も全て同じ順番で並んでいること。
-----------------------------------
# coding:WINDOWS-31J
include Math
ofp = File.open("合成結果.csv","w")
File.open("X.csv") do |xfile|
File.open("Y.csv") do |yfile|
File.open("Z.csv") do |zfile|
lno = 0
while xline = xfile.gets
yline = yfile.gets
zline = zfile.gets
lno += 1
#見出し行の場合
if lno == 1
ofp.print xline
next
end
#以降の行の場合
#改行削除
xline.chomp!
yline.chomp!
zline.chomp!
#カンマで分割
arrx = xline.split(/,/)
arry = yline.split(/,/)
arrz = zline.split(/,/)
#出力用Array作成
new_arr = Array.new
#観測点格納
new_arr << arrx[0]
#合成速度計算
(1...arrx.size).each do |i|
v = arrx[i].to_f * arrx[i].to_f + arry[i].to_f * arry[i].to_f + arrz[i].to_f * arrz[i].to_f
v = sqrt(v)
#vstr = v.to_s
vstr = sprintf("%.9f",v)
new_arr << vstr
end
#合成結果出力
ofp.print new_arr.join(","),"\n"
end
end
end
end
ofp.close
    • good
    • 0
この回答へのお礼

tatsu99さま
前回からありがとうございます。
arrx[i].to_f のように各ファイルのセルごとに配列に入れて、それぞれを計算させるということですか。
ruby、ちょっとかじり始めたのですが、複数ファイルの同時読み込みから書き出しとなると、まだまだ全然です。
教えてください。

ごくまれになんですが、見出しがない場合のファイルがありまして、その場合は
11から16行目だけを
#lno += 1
#見出し行の場合
#if lno == 1
#ofp.print xline
#next
#end
コメントアウトすればよいのでしょうか?
それとも一応7行目の
lno = 0
に関してもコメントアウトあったほうがいいのでしょうか?

お礼日時:2018/10/18 13:19

>arrx[i].to_f のように各ファイルのセルごとに配列に入れて、それぞれを計算させるということですか。


回答:
はい。arrx[i]は、文字列なので、arrx[i].to_fで浮動小数点数に変換してから計算します。

X=arrx[i].to_f
Y=arry[i].to_f
Z=arrz[i].to_f
v = sqrt(X*X + Y*Y + Z*Z)
としても同じです。

>11から16行目だけを
>#lno += 1
>#見出し行の場合
>#if lno == 1
>#ofp.print xline
>#next
>#end
>コメントアウトすればよいのでしょうか?
回答:
以下の行のみ、コメントアウトすればOKです。
if lno == 1
ofp.print xline
next
end

但し、見出し行がない場合は、X.csv,Y.csv,Z.csvの3ファイル共に、見出し行がないことが必要です。
1つ又は2つのファイルのみ見出し行がないケースは想定していません。
    • good
    • 0
この回答へのお礼

ありがとうございます。
X=arrx[i].to_f
Y=arry[i].to_f
Z=arrz[i].to_f
v = sqrt(X*X + Y*Y + Z*Z)
としても同じです。
の説明がとても分かりやすく助かります。
ベストアンサーとさせていただきます。

お礼日時:2018/10/18 14:11

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!