열의 (가중치) 대다수를 계산하는 방법은 무엇입니까?

열의 (가중치) 대다수를 계산하는 방법은 무엇입니까?

두 개의 파일이 있습니다. 첫 번째 파일에는 첫 번째 열이 ID이고 나머지 열이 투표인 행이 포함되어 있습니다.

3242 -1 1 -1 1 1 1

첫 번째 단계로 대부분의 ID를 계산하고 싶습니다. 위의 예에서는 찬성 투표가 반대 투표보다 많기 때문에 투표는 1입니다. 다음 줄을 사용하여 결과를 출력 파일에 저장하고 싶습니다.

3242 1

또한 해당 투표의 "가중치"가 포함된 파일도 있습니다.

3242 0.9 0.1 0.9 0.2 0.1 0.2

두 번째 단계로, 다양한 라인에 대한 가중치 투표를 계산하고 싶습니다. 이 경우에는

(0.9 * -1) + (0.1 * 1) + (0.9 * -1) + (0.2 * 1) + (0.1 * 1) + (0.2 * 1) = -1.2

결과는 부정적이므로 투표는 -1이 되어야 합니다. 다시 한번 말하지만, 각 줄에 ID와 결과 투표가 포함된 출력 파일에 이것을 저장하고 싶습니다.

awk나 Perl을 사용하여 이를 달성할 수 있습니까?

답변1

#!/usr/bin/perl

use List::MoreUtils qw(pairwise);
use List::Util qw(sum);
use strict;

sub read_file {
    my ($filename) = @_;
    open F, '<', $filename or die "Could not open $filename: $!";
    my %data;
    while (<F>) {
        my ($id, @data) = split;
        $data{$id} = \@data;
    }
    close F;
    return %data;
}

sub output_file {
    my ($filename, %data) = @_;
    open F, '>', $filename or die "Could not open $filename: $!";
    for (sort keys %data) {
        print F "$_\t$data{$_}\n";
    }
    close F;
}

my %votes = read_file 'votes.tsv';
my %weights = read_file 'weights.tsv';

my %unweighted;
while (my ($id, $data) = each(%votes)) {
    my $sum = List::Util::sum(@$data);
    $unweighted{$id} = $sum < 0 ? -1 :
                       $sum > 0 ? +1 : 0;
}
output_file('unweighted.tsv', %unweighted);

my %weighted;
while (my ($id, $data) = each(%weights)) {
    my $dot_prod = sum(pairwise { $a * $b } @{$votes{$id}}, @$data);
    $weighted{$id} = $dot_prod < 0 ? -1 :
                     $dot_prod > 0 ? +1 : 0;
}
output_file('weighted.tsv', %weighted);

관련 정보