前提・実現したいこと
以下のtest.csvを読み込み, 分割属性(天気など), と対応する属性値(晴など), ゴルフプレイ(○, ×)の頻度を求めるプログラムを作成したいです。
test.csv
1天気 温度 湿度 風 ゴルフプレイ 2晴 暑 高 無 × 3晴 暑 高 有 × 4曇 暑 高 無 ○ 5雨 暖 高 無 ○ 6雨 涼 普通 無 ○ 7雨 涼 普通 有 × 8曇 涼 普通 有 ○ 9晴 暖 高 無 × 10晴 涼 普通 無 ○ 11雨 暖 普通 無 ○ 12晴 暖 普通 有 ○ 13曇 暖 高 有 ○ 14曇 暑 普通 無 ○ 15雨 暖 高 有 ×
ちなみに, 最終的には以下のように出力されるのが目標です。
天気 -> 雨 -> ○ = 3 天気 -> 雨 -> × = 2 天気 -> 晴 -> × = 3 天気 -> 晴 -> ○ = 2 天気 -> 曇 -> ○ = 4 風 -> 無 -> × = 2 風 -> 無 -> ○ = 6 風 -> 有 -> × = 3 風 -> 有 -> ○ = 3 湿度 -> 高 -> ○ = 3 湿度 -> 高 -> × = 4 湿度 -> 普通 -> ○ = 6 湿度 -> 普通 -> × = 1 ...
発生している問題・エラーメッセージ
csvファイルの読み込みと頻度表示はできたのですが, 出力結果がアドレス表示になってしまっています。その原因がよく分からないので教えてほしいです。
該当のソースコード
Perl
1#!/usr/bin/perl 2use strict; 3use Encode; 4use utf8; 5 6main(); 7 8sub main { 9 my %TrainData=mkDataHash("test.csv"); 10 11 foreach my $tag (keys %TrainData) 12 { 13 foreach my $data (keys %{$TrainData{$tag}}) 14 { 15 foreach my $det (keys %{$TrainData{$tag}{$data}}) 16 { 17 my $f = $TrainData{$tag}->{$data}->{$det}; 18 print("$TrainData{$tag}->$TrainData{$data}->$TrainData{$det}-->$f\n"); 19 } 20 } 21 } 22} 23 24sub mkDataHash { 25 my($csv_name)=shift(@_); 26 open(my $IN,$csv_name); 27 my $data_utf8=<IN>; 28 my @Tag=split(/\t/,decode_utf8($data_utf8)); 29 my %TrainData; 30 chomp($data_utf8); 31 while(my $data_utf8=<$IN>) { 32 chomp($data_utf8); 33 my @Data=split(/\t/,decode_utf8($data_utf8)); 34 my $det=pop(@Data); 35 my $i; 36 for($i=0; $i<=$#Data; $i++) 37 { 38 my $tag = $Tag[$i]; 39 my $data = $Data[$i]; 40 $TrainData{$tag}->{$data}->{$det}++; 41 } 42 } 43 close($IN); 44 return %TrainData; 45}
試したこと
配列でなければpop関数が使えないことに気づいたので新たに@list関数を追加しました。また, それに伴ってタブで区切られているところをsplit関数で表現してみました。ファイルの読み込みが以前実行したときにはできていなかったので, やり方を調べて修正しました。ファイルの読み込みと同じ要領でfor文を利用してtagとdataを処理してみました。
補足情報
Ubuntu-20.04を利用しています。
回答3件
あなたの回答
tips
プレビュー