• 締切済み

perlで一定の範囲ごとにカウントさせる方法について教えてください。

perlで一定の範囲ごとにカウントさせる方法について教えてください。 例えば、data.txtに、-10≦n≦10の範囲で様々な数が入ったファイルがあるとして、 -10.0 ≦ x < -9.9 -9.9 ≦ x < -9.8 .... 9.8 ≦ x < 9.9 9.9 ≦ x ≦ 10.0 (←最後は≦のほうがいいですが、<でもOK) と0.1ごとに区切って、 その範囲に入る数をカウントしたいとき、 ifや+=を使って範囲を指定して、カウントアップさせる方法もありますが、 指定したい範囲の数が多いと、ifばかりをプログラム内に羅列するのは面倒です。 できれば以下のような結果が表示されるとうれしいのですが… 中間値 カウント数 -9.95 3 -9.85 6 ... すっきりした書き方はありませんか?よろしくお願いします。

みんなの回答

  • SaLeeFA
  • ベストアンサー率66% (6/9)
回答No.5

他の人の回答見てませんけども。 何に使うデータで、そのあとどのように、どの程度使うのかは分かりませんが。 テストはしてません。正規表現部分は都合に合う様に好きにして下さい。 ----------------------------------------------- @data; #全ての数値が入っている物とする。 foreach (@data){ { m/([0-9]+\.[0-9]?)/ } $count{"$1"}++; } ------------------------------------------------- 中間値とカウント数のの意味は分かりませんでしたが、 ハッシュのデータをごにょごにょしてカウント数から導き出せる数値は全部出せます。

全文を見る
すると、全ての回答が全文表示されます。
  • shiren2
  • ベストアンサー率47% (139/295)
回答No.4

テストは行っていませんので、バグがあるかもしれませんが…。 参考までにどうぞ。 インデントは全角スペースになっています。 #!/usr/bin/perl use strict; use POSIX; open(IN, "data.txt") or die; my %hash; while(<IN>){  # 2桁目以降の端数を切り上げ  my $n = &ceil($_*10)/10;  # インクリメント  $hash{$n}++; } print "中間値\tカウント数\n"; for(sort{ $a <=> $b } keys %hash){  # -10.0から-9.9(keyは-9.90)を、-9.95と表示  printf("%.2f\t%d\n", $_-0.05, $hash{$_}); }

全文を見る
すると、全ての回答が全文表示されます。
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

今回の条件(上限下限が決まっている。定間隔)だったら $val=( 読み込んだ値 ) だとして、 $minval = -10 ; # 最小値 $maxval = 10 ; # 最大値 $stepval = 10 ; # 0.1の逆数 if ( $val < $min ) { $level = 0 ; } elsif ( $val >= $maxval ) { $level= 199; # ≦10のための処理 }else{ $level =int(($val - $minval) * $stepval) ; #区間番号0~199 } $count[ $level ] += 1 ; 表示は for($i=0;$I<200;++$i){ $start = $minval + $i / $stepval ; $end = $minval + ($i+1) / $stepval ; $mid = ($start + $end)/2 ; printf "%5.2f %d\n", $mid, $count[$i]; }

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

一定範囲ごとにカウントしたい場合、 一般的には大きい数字から比較していけばよいと思うのだけどそれじゃだめですか? 実験は面倒なので理論だけ。(未テストです) イメージ的には my @floor = ( -9.9 -9.8 -9.7 -9.6 ); # 比較したい数字を降順にしたもの my @count = () # カウントの結果 my $value = -9.75; # txtから読み取った数字 count_loop: for( my $N=0; $N<$#floor; $N++ ) { if( $floor[$N] <= $value ) { $count[$N] ++; last count_loop; } } テキストの中身が範囲内に収まっているのならこれで十分かなーとおもうけど 後は表示するときに、 増分の半分を $floorに足してあげれば中央値になるかなー?

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

たとえば sub check_inclusive_exclusive { my ($left, $right) = @_; sub { $left <= $_[0] && $_[0] < $right; }; } sub check_inclusive_inclusive { my ($left, $right) = @_; sub { $left <= $_[0] && $_[0] <= $right; }; } my @counts; for (-100 .. 98) { my $left = $_ / 10.0; my $right = ($_+1) / 10.0; my $mid = ($_+0.5) / 10.0; push @counts, +{ left => $left, right => $right, mid => $mid, check => check_inclusive_exclusive($left, $right) }; } push @counts, +{ left => 9.9, right => 10.0, mid => 9.95, check => check_inclusive_inclusive(9.9, 10.0) }; for my $count (@counts) { $count->{count} = 0; } open my $fh, '<', 'data.txt'; while (<$fh>) { for my $count (@counts) { ++$count->{count}, last if $count->{check}($_); } } とする手はあると思うけど, これでうれしいかどうかは知らん.

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • プログラム/perl カウントについて

    プログラム初心者です. 現在,プログラムの書き換えを行っているところです. (言語はperlです 以下のプログラムのnextの前に, 「$bbをカウントし, $bbが2回出てきたらlast」 というプログラムを書きたいと思っています. ------------------------ if($honbun =~ /$boundary/) { $bb++;         if($bb >=2)         {      last; } next; } ---------------- カウントする変数を使うべきだと思うのですが,どのようにすればいいでしょうか; 初心者質問で申し訳ないです.

  • エクセルである指定した範囲のカウント

    エクセルで通常カウントは、以下のように、B2:B5と範囲指定しますが、 COUNTIF(B2:B5,">55") ある一定のセルをカウントしようとしたのですが、うまくいきません・・・。 たとえば、E8,G8I8をカウントの対象としたいとき、書式はどのようにすればいいでしょうか? やりたいことは、上記のように、そろってない範囲のセルで、17以上はいくつか?など、ある数値以上になっているセルの数をカウントすることです。

  • Perl。文字出現回数を重複しないでカウントしたい。

    perl初心者です。どうぞ助けて下さい。 以下のようにデータがならんでいる時、 pphhhppphhhppppppphhppppppppppppppppppphhh pが連続した文字の連続数は 2、3、7、19 となります。 今、知りたいのはこのようなpの連続数の出現回数です。つまり、たとえばpが19回連続してあるものは何回でてきたか、が知りたいのです。 上の例だと1回が正解となります。 ところが、スクリプトを書くとき、 たとえば以下のようにしたとき、 pが19回なら重複カウントはなくても、 pを2でカウントしたら、 本当に出てきて欲しいこたえは一回なのに、 P=3、7、19のどれにも該当してしまいます。 #!/usr/bin/perl ; open(IN, "text1.txt") or die ; open(OUT, ">text1out.txt"); while(<IN>) { chomp ; if (/(\S+)/) { $name = $1 ; if ($name =~ /^ppppppppppppppppppp/) { {$count++;} ; } print OUT "$count\n" ; } } close (IN) ; close (OUT) ; 正規表現の中を工夫すればいいのだと思いますが、 大変困っております。宜しくお願いします。

    • ベストアンサー
    • Perl
  • perl ファイルのデータを編集したい

    初めまして、perl をやり初めたばかりです。作業は Linux 上で行ってます。 あるテキストファイル data.txt があります。 data.txt の中は、以下のようになっているとします。 100 200 300 400 500 600 これを読み込んで、例えば、 1 2 3 4 5 6 以上の様に各数字を百分の一にして出力したいと思ってます。 一応、色々と調べながらプログラムを書いてはみましたが 思う様に出力されません。以下そのプログラム。 #!/usr/bin/perl open(IN, "data.txt") or die ; @x = <IN>; close (IN); $ref_x = \@x; $n_data = @x; for ($i = 0; $i< $n_data; ++$i) { $$ref_x[$i] /= 100 ; print $x[$i], " "; } print"\n"; どなたか、perl にお詳しい方教えていただけないでしょうか? 宜しくお願い申し上げます。

  • 数値のカウント

    列、行、共に100セル位の中から、特定の数字を指定しカウントしたいのですが 上手く出来ません。 *今の方法 ・SUMIFで範囲を指定し、カウントしたい数値を指定 ・返ってくる数値は指定した数値を合計した数  (例・5をカウントさせると、20を返してくる。指定範囲を見ると5が4個ある) *したい事 ・合計せずにカウントだけしたい ヒントや方法などアドバイスお願いします

  • Excelの範囲内カウント方法について

    Excelの指定した範囲内のセルに入力されている国語、数学、社会の個数をカウントしたい場合です。カウントイフの数式+でつなぐ方法しかないんですか?

  • Perlのプログラミングについて

    Perlのプログラミングでつまづきました。 # ファイルから指定文字列を含む行を収集する # 入力ファイルのオープンと読み込み print( "入力ファイル名?" ); $n = <STDIN>; chomp( $n ); open( FIN, "<$n" ) or die "入力ファイルオープンエラー: $!\n"; $n = @a = <FIN>; close( FIN ); print( "$n 行読み込みました\n" ); # 行の収集 print( "検索文字列?" ); $x = <STDIN>; chomp( $x ); $ptn = $x; #指定の文字列 $x = @b = grep( /$ptn/, @a ); print( "$x 行見つかりました\n" ); # 出力ファイルのオープンと書き出し print( "出力ファイル名?" ); $y = <STDIN>; chomp( $y ); open( FOUT, ">$y" ) or die "出力ファイルオープンエラー: $!\n"; print FOUT ( $ptn, "\n" ); print FOUT ( $x, "\n" ); print FOUT ( @b ); close( FOUT ); というプログラムで実行すると C:\My Perl\pl>perl プログラムの実行.pl 入力ファイル名?sample1.txt 168 行読み込みました 検索文字列?k 45 行見つかりました 出力ファイル名?out3-24.txt 続行するには何かキーを押してください . . . となり出力ファイルの中身が表示されません。 どこを間違えているのかご指摘いただけないでしょうか?

  • カウントの方法を教えて下さい。

    カウントの方法を教えて下さい。 Excel2003を使っています。A1~E30のセルに11~51、12~52、13~53・・・の数字がバラバラに入力されています。 この範囲の中から頭の数字が1、2、3、4、5が付く数をカウントしたいのですが、宜しくお願いします。

  • terapadを使って、perlについての問題です。

    terapadを使って、perlについての問題です。 第一問はある英語の文書ファイルから、その文書の段落の数、文の数、単語の数をカウントするプログラム。段落の区きりが改行で、文の区きりは、「 .」(半角スペース2個に.1個)で、文字の区きりは、「 」(半角スペース)あるとする。 第二問はある単語ファイル(例えばtest.txt)に乗っている単語リスト(1行1単語)の単語の意味を調査し(辞書は先に用意したファイルで調査するdictionary.txt)、その結果をファイルに保存するプログラムを作成するプログラム。(ファイル名をout.txtする)そのプログラムを提出すること。 誰か教えてください、プログラミングの初心者なので…全く思いつかない。><

  • perl文末文字列カウントプログラム

    perl の文字列カウント こんにちは。初質問になります。perのlプログラミングについての質問です。 ある文章の「文末」の文字列をカウントし、出力するプログラムをつくりたいと思っています。 以下の文字列カウントプログラムを元に作りたいのですが、正規表現の文末指定のつけどころが恥ずかしながらわかりません。 <テキストデータ例> やまだくんはみかんを食べています!!たかしくんはりんごを食べています!! ひろしくんは好きなみかんを食べています!! ??よしこさんは嫌いなりんごを食べていますか?? かなえさんはいつもぶどうを食べています(^-^) ひろしくんはみかんが好きです(^-^)しかし、ゆうじくんはみかんは好きではありません(^-^) ひろみさんはみかんとぶどうは嫌いです!!しかし、りんごは好きです。 たとえば上のテキストデータを読み込み 文末のビックリマーク、クエスチョンマークの文字列を検出し 個数をカウントし出力するするようなプログラムです。 <出力結果> (^-^) 2 !! 2 ?? 1 となるようにしたいです。 以下のプログラムだと文末に限らずリストにあてはまる全ての記号がカウントされてしまいます。 @arr = qw('(^-^)','!!','??' ); $fname = "input.txt"; open(IN,"$fname") || &error("Can't open $fname"); read(IN,$buff,-s IN); close (IN); foreach (@arr){ $cnt = scalar( () = $buff =~ /$_/g ); print "$_ $cnt\n"; }