2010-11-08 37 views
0

J'ai une donnée qui ressemble à ceciClustering Par intervalle Via Hash de tableau Perl

#Status value 
TP  5.000 
TP  3.000 
TP  3.000 
TN  10.000 
TP  2.000 
TP  9.000 
TN  1.000 
TP  9.000 
TN  1.000 

Ce que nous voulons faire est de regrouper l'état en fonction de l'intervalle donné value. Laissez cet intervalle être 1-3, 4-6, 7-9, 10-12, etc .. (c'est-à-dire la taille de bac 3).

Nous espérons obtenir le hachage du tableau comme ceci:

my %hoa = (
'1-3' => [TP,TP,TP,TN,TN], 
'4-6' => [TP], 
'7-9' => [TP,TP], 
'10-12' => [TN]); 

Quelle est la façon d'y parvenir?

Mise à jour: Correction du HoA pour 7-9, grâce à ysth.

Répondre

2

le code abstraire de déterminer l'intervalle:

sub interval { 
    my ($val) = @_; 
    my $i = int(($val + 2)/3); 
    my $interval = sprintf('%d-%d', $i * 3 -2, $i * 3); 
    return $interval; 
} 

my %hoa; 
while (my $line = <>) { 
    next if $line =~ /^#/; 
    my ($status, $value) = split ' ', $line; 
    push @{ $hoa{ interval($value) } }, $status; 
} 

use Data::Dumper; 
print Dumper \%hoa; 

(qui obtient deux pour TPs 7-9, pas un comme vous montrer).

2

La réponse d'ysth a été la première chose qui m'est venue à l'esprit, et je pense qu'il a la bonne approche. Je voudrais juste laisser une suggestion: vous pourriez utiliser un algorithme de clustering pour faire cela pour vous dans un avenir proche (par exemple, lorsque vos données deviennent multidimensionnelles). K-means, par exemple, fonctionnerait bien, même pour des données 1D telles que la vôtre.

Par exemple:

use strict; use warnings; 
use Algorithm::KMeans; 

my $datafile = $ARGV[0] or die; 
my $K  = $ARGV[1] or 0; 
my $mask  = 'N1'; 

my $clusterer = Algorithm::KMeans->new(
    datafile => $datafile, 
    mask  => $mask, 
    K  => $K, 
    terminal_output => 0, 
); 

$clusterer->read_data_from_file(); 

my ($clusters, $cluster_centers) = $clusterer->kmeans(); 

my %clusters; 

while (@$clusters) { 

    my $cluster = shift @$clusters; 
    my $center = shift @$cluster_centers; 

    $clusters{"@$center"} = $cluster; 
} 

use YAML; print Dump \%clusters;