【问题标题】:Count decade occurrences计算十年发生次数
【发布时间】:2012-02-07 08:14:36
【问题描述】:

文件:

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个三十... 我希望你现在这样做。一个 python 脚本会很棒。

期望的输出:

0    6
1    4
2    5
3    4
10    2

【问题讨论】:

  • 数十年(我认为这是正确的英文)
  • 朋友的英语没问题。只是无法从 E.g. 5 thirties 理解您想要的输出 .. 其余的行并没有真正帮助(如果您知道我的意思);) 如果您可以使用您的 infile 提供所需的输出,那将有所帮助。
  • 但是只有3个三十!
  • @katrielalex - 我认为第二个数字无关紧要。有 5 行第一个数字是 30,所以我假设这只是他关心的第一个数字。
  • @AxelWilhelmEinarsson 感谢您提供所需的输出。在混合中添加了我的答案。希望有帮助

标签: python perl unix awk grep


【解决方案1】:

我不太了解您在这里尝试做什么,但我认为您正在寻找像这样简单的东西

from collections import defaultdict
decades = defaultdict(int)
for line in open('infile.txt', 'r'):
    decades[int(line.split()[0]) / 10] += 1
for decade, count in decades:
    print "%s people in their %s0s" % (count, decade * 10)

【讨论】:

  • 我认为这个版本会将第二列的值与第一列的不同值相加,所以不完全是 OP 要求的......
  • 当我发布我的答案时他没有示例,所以我不得不猜测他想要什么。我将编辑我的答案以回答实际问题。
【解决方案2】:

对于 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

【讨论】:

    【解决方案3】:

    如果我理解正确:

    perl -ne '{use integer; $i{$_/=10}++} END{ map { print $_*10," : $i{$_}\n" } sort keys %i }'
    

    【讨论】:

      【解决方案4】:

      我认为这个 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
      

      您可能需要不同的输出,但应该很容易自定义...

      更新:

      对于 OP 所需的输出更改:

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

      print( "{} {}".format( 
                      key , count ) )
      

      【讨论】:

        【解决方案5】:

        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
        

        【讨论】:

        • 顺利,我认为我的旧单线是 awk。
        • 不客气,阿克塞尔。很高兴我能帮忙。感谢您接受它和投票。 :)
        • 您可以通过在awk 中包含sort 来进一步缩短它。我应该早点做的。但在这里 - awk '{x=$1/10; a[int(x)]++} END{for (i in a) print i,a[i] | "sort -n"}' INPUT_FILE
        【解决方案6】:

        在 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
        

        【讨论】:

        • 看起来不错但是...对于 k, v in sorted(c): TypeError: 'int' object is not iterable
        • @AxelWilhelmEinarsson:抱歉,现在修好了。
        【解决方案7】:

        其他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
        

        【讨论】:

        • 对一组紧密的数字使用哈希是一种浪费,IMO。也可以将其存储在 $h[ int( $F[0] / 10 ) ] 中。
        【解决方案8】:

        单行 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)]
        

        【讨论】:

          【解决方案9】:

          这是一个简短的 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

          【讨论】:

            【解决方案10】:

            这可能对你有用:

            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/'
            

            【讨论】:

              【解决方案11】:

              另一种方法:

              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
              

              如果可用,可以使用-Esay 进一步缩短。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2014-06-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-01-02
                • 2021-10-13
                • 1970-01-01
                相关资源
                最近更新 更多