人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

データ処理に関する質問です.皆さんの手助けのおかげで,以下のような二つのファイルを作ることができました.

a_1.txt(各テストの得点.例えばtest1の"1→3"はtest1の1問目が3点だったことを表す)

test1
1→3
2→2
3→2
4→5

test2
1→2
2→3
3→2
4→3
3→3


a_2.csv(a_1の点数にそれぞれ対応している)

id=test2=,8,2,5,6,1,
id=test1=,4,2,1,4,

この2つから新しい3つめのファイルを作ろうと思っています.
まずa_2.csvの8,2,5,6,1,4,2,1,4の平均を求めます.この場合は3.66です.これよりa_2のデータの数字が大きい場合は得点を2倍にして,小さい場合は半分にして,新たな得点を出力させたいです.
例えば,test1の1の得点は3点ですが,a_2を見ると4が対応していて,これは3.66より大きいので2倍になり,
1→6
と出力させたいです.

全体として,a_1と同じような形式にして保存したいと思っています.
かなりの数のデータがあるので,Perlで処理するのがいいと思ってるんですけど手を貸していただけたら嬉しいです.


●質問者: ishikennn
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:CSV Perl txt テスト データ
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● imo758
●35ポイント ベストアンサー

こういうことかな?合ってるか自信ないですが。運用は自己責任でよろしく。

open A_1, "<a_1.txt" or die "A_1 open error";
while(<A_1>){
if(/^(\d+)[^\d]+(\d+)$/){
${$a_1{$id}}[$1] = $2;
}else{
chomp;
$id = $_;
}
}
close A_1;

open A_2,"<a_2.csv" or die "A_2 open error";
while(<A_2>){
/^id=(test\d+)=([\d\,]+)$/ or die "error A_2 matching";
($id, $points) = ($1, $2);
@{$a_2{$id}} = (split /,/, $points);
$num += $#{$a_2{$id}};
map{$sum += $_;} @{$a_2{$id}};
}
close A_2;
$avarage = $sum / $num;

foreach$id(keys %a_1){
print "$id\n";
for($i=1; $i<=$#{$a_1{$id}}; $i++){
$point1 = ${$a_1{$id}}[$i];
$point2 = ${$a_2{$id}}[$i];
printf "$i→%d\n", (($avarage < $point2) ? $point1*2 : ($avarage == $point2 ? $point1 : $point1/2));
}
}
◎質問者からの返答

ちゃんと動きました!ありがとうございます.

test1とかtest2以外に,例えばanswer1とかanswer2とかがあったとすると,正規表現の/^id=(test\d+)=([\d\,]+)$/のあとにor /^id=(answer\d+)=([\d\,]+)$/を追加すればいいんですかね?


2 ● imo758
●35ポイント

汎用性損ねてすいません。それならいっそのこと

/^id=(test\d+)=([\d\,]+)$/

ではなく

/^id=(\w+\d+)=([\d\,]+)$/

のほうがいいかもしれません

◎質問者からの返答

正規表現でそういうことも表現できるんですね.便利です.

ありがとうございました!

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ