Посчитать десятилетия - PullRequest
       13

Посчитать десятилетия

0 голосов
/ 11 января 2012

infile:

1   3
2   3
3   3
4   3
8   3
9   3
12  3
14  3
18  3
19  3
20  3
25  3
26  3
27  3
28  3
30  3
31  3
32  3
36  3
38  3
101 3
109 3

Однажды я узнал один лайнер для подсчета событий за десятилетие.Например, 5-30 лет ... Я надеюсь, что вы делаете сейчас.Сценарий Python был бы потрясающим.

Желаемый вывод:

0    6
1    4
2    5
3    4
10    2

Ответы [ 11 ]

5 голосов
/ 11 января 2012

В Perl используйте хеш:

use warnings;
use strict;

my %decs;
while (<DATA>) {
    my ($n) = /([0-9]+)/;
    my $x = int($n / 10);
    $decs{$x}++;
}
print "$_ $decs{$_}\n" for sort { $a <=> $b } keys %decs;

__DATA__
1   3
2   3
3   3
4   3
8   3
9   3
12  3
14  3
18  3
19  3
20  3
25  3
26  3
27  3
28  3
30  3
31  3
32  3
36  3
38  3
101 3
109 3

Вывод:

0 6
1 4
2 5
3 5
10 2
2 голосов
/ 11 января 2012

awk однострочник для вас -

awk '{x=$1/10; a[int(x)]++} END{for(i in a) print i,a[i] | "sort -n"}' INPUT_FILE

Тест:

[jaypal:~/Temp] cat file
1   3
2   3
3   3
4   3
8   3
9   3
12  3
14  3
18  3
19  3
20  3
25  3
26  3
27  3
28  3
30  3
31  3
32  3
36  3
38  3
101 3
109 3

[jaypal:~/Temp] awk '{x=$1/10; a[int(x)]++} END{for(i in a) print i,a[i] | "sort -n"}' file
0 6
1 4
2 5
3 5
10 2
0 голосов
/ 11 января 2012

Другой подход:

perl -ne '$h{$.=$_/10}++}{print"$_ $h{$_}\n"for sort{$a-$b}keys%h' infile.txt

Вывод:

0       6
1       4
2       5
3       5
10      2

Может быть дополнительно сокращен с помощью -E и say, если доступно.

0 голосов
/ 11 января 2012

Это может работать для вас:

sed 's/\S\s*\S*$//;s/^$/0/' file | uniq -c | sed 's/\s*\(\S*\)\s\(\S*\)/\2\t\1/'
0       6
1       4
2       5
3       5
10      2

Выглядит так, как будто ваши данные отсортированы, если не вставить sort -n примерно так:

sed 's/\S\s*\S*$//;s/^$/0/' file | sort -n | uniq -c | sed 's/\s*\(\S*\)\s\(\S*\)/\2\t\1/'
0 голосов
/ 11 января 2012

Вот короткий в Perl:)

perl -nE 'END{say"$_\t$h{$_}"for sort{$a<=>$b}keys%h}++$h{$_/5>>1}' input.txt
0       6
1       4
2       5
3       5
10      2
0 голосов
/ 11 января 2012

Однострочное решение для Python itertools (должно работать для Python> = 2.4):

>>> from itertools import groupby
>>> sorted((key, len(list(group))) for key, group in groupby(
...        int(line.split()[0]) // 10 for line in open('infile')))
[(0, 6), (1, 4), (2, 5), (3, 5), (10, 2)]
0 голосов
/ 11 января 2012

Другое perl решение:

perl -ane '
  $h{ int( $F[0] / 10 ) }++;
  END {
    for $num ( sort { $a <=> $b } keys %h ) {
      printf qq[%d\t%d\n], $num, $h{ $num }
    }
  }
' file

Результат:

0       6
1       4
2       5
3       5
10      2
0 голосов
/ 11 января 2012

В Python 2.7:

from collections import Counter
c = Counter(int(line.split()[0]) // 10 for line in open("infile"))
for k, v in sorted(c.iteritems()):
    print k, v
0 голосов
/ 11 января 2012

Я думаю, что этот модуль Python будет делать то, что вам нужно:

import sys
import math
from collections import OrderedDict 

def count_decades( infile ):
    decade_counts = OrderedDict()
    for line in infile:
        number = int( line.split( ' ' )[ 0 ] )
        decade_index = int( math.floor( number / 10 ) )
        decade_counts[ decade_index ] = decade_counts.get( decade_index, 0 ) + 1
    return decade_counts

if __name__ == '__main__':    
    with open( sys.argv[ 1 ], 'r' ) as infile:
        decade_counts = count_decades( infile )        
        for key, count in decade_counts.items():
            print( "{} - {} occurs {} times".format( 
                key * 10 , key * 10 + 9, count ) )

Когда вызывается так:

python occur.py decades.txt

Результат:

0 - 9 occurs 6 times
10 - 19 occurs 4 times
20 - 29 occurs 5 times
30 - 39 occurs 5 times
100 - 109 occurs 2 times

Может потребоваться другой вывод, но его легко настроить ...

UPDATE:

Для ОП желаемое изменение выхода:

print( "{} - {} occurs {} times".format( 
                key * 10 , key * 10 + 9, count ) )

до

print( "{} {}".format( 
                key , count ) )
0 голосов
/ 11 января 2012

если я правильно понял:

perl -ne '{use integer; $i{$_/=10}++} END{ map { print $_*10," : $i{$_}\n" } sort keys %i }'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...