【问题标题】:How to calculate the percentage of each element in a list?如何计算列表中每个元素的百分比?
【发布时间】:2017-01-03 18:50:08
【问题描述】:

我有这个包含 5 个数字序列的列表:

['123', '134', '234', '214', '223'] 

并且我想获得每个数字1, 2, 3, 4 在每个数字序列的ith 位置的百分比。比如这个5数字序列在0th位置的数字是1 1 2 2 2,那么我需要计算百分比 1, 2, 3, 4 在这个数字序列中,并将百分比作为新列表的0th 元素返回。

['123', '134', '234', '214', '223']

0th position: 1 1 2 2 2   the percentage of 1,2,3,4 are respectively: [0.4, 0.6, 0.0, 0.0]

1th position: 2 3 3 1 2   the percentage of 1,2,3,4 are respectively: [0.2, 0.4, 0.4, 0.0]

2th position: 3 4 4 4 3   the percentage of 1,2,3,4 are respectively: [0.0, 0.0, 0.4, 0.6]]

那么想要的结果就是返回:

[[0.4, 0.6, 0.0, 0.0], [0.2, 0.4, 0.4, 0.0], [0.0, 0.0, 0.4, 0.6]]

到目前为止我的尝试:

list(zip(*['123', '134', '234', '214', '223']))

结果:

 [('1', '1', '2', '2', '2'), ('2', '3', '3', '1', '2'), ('3', '4', '4', '4', '3')]

但是我卡在这里了,然后我不知道如何计算1, 2, 3, 4的每个数字的元素的百分比,然后得到想要的结果。任何建议表示赞赏!

【问题讨论】:

    标签: python list python-3.x


    【解决方案1】:

    从您的方法开始,您可以使用 Counter 完成剩下的工作

    from collections import Counter
    
    for item in zip(*['123', '134', '234', '214', '223']):
        c = Counter(item)
        total = sum(c.values())
        percent = {key: value/total for key, value in c.items()}
        print(percent)
    
        # convert to list
        percent_list = [percent.get(str(i), 0.0) for i in range(5)]
        print(percent_list)
    

    打印出来的

    {'2': 0.6, '1': 0.4}
    [0.0, 0.4, 0.6, 0.0, 0.0]
    {'2': 0.4, '3': 0.4, '1': 0.2}
    [0.0, 0.2, 0.4, 0.4, 0.0]
    {'4': 0.6, '3': 0.4}
    [0.0, 0.0, 0.0, 0.4, 0.6]
    

    【讨论】:

      【解决方案2】:

      您可以像以前一样创建压缩列表:

      zipped = zip(*l)
      

      然后将itertools.Counter 映射到它,以便从zip 获取结果中每个项目的计数:

      counts = map(Counter, zipped)
      

      然后遍历它,根据它们的数量除以它们的大小创建一个列表:

      res = [[c[i]/sum(c.values()) for i in '1234'] for c in counts]
      print(res) 
      [[0.4, 0.6, 0.0, 0.0], [0.2, 0.4, 0.4, 0.0], [0.0, 0.0, 0.4, 0.6]]
      

      如果你是一个单行的人,请将理解中的前两个混为一谈:

      res = [[c[i]/sum(c.values()) for i in '1234'] for c in map(Counter, zip(*l))]
      

      此外,如评论中所述,如果您不提前知道元素,sorted(set(''.join(l))) 可以替换 '1234'

      【讨论】:

      • 如果你不提前知道元素,set(''.join(l))应该替换'1234'
      • @Jim Fasarakis-Hilliard 感谢您的解决方案,但我不太了解 [[c[i]/sum(c.values()) for i in '1234'] for c in map(Counter, zip(*l))] 这个语法,因为我对 map 函数不是很熟悉。我检查并知道它可能意味着在 zip(*l)) 上应用函数 Counter ,然后我想为什么不直接使用 Counter(zip(*l)) ,但我发现 Counter(zip(*l)) 不起作用。然后我检查并发现 map(Counter, zip(*l)) 返回 <map object at 0x033C1930> 。我不知道这意味着什么。你能解释一下为什么map(Counter, zip(*l)) 有效吗?谢谢。
      【解决方案3】:

      您可以使用count(i)来确定数字1-4的出现次数,然后除以5得到百分比:

      sequence=list(zip(*['123', '134', '234', '214', '223']))
      percentages=[]
      for x in sequence:
          t=list(x)
          temp=[t.count(str(i))/len(x) for i in range(1,5)]  #work out the percentage of each number
          percentages.append(temp) #add percentages to list
      

      或者,作为一个列表理解:

      percentages=[[list(x).count(str(i))/len(x) for i in range(1,5)]for x in sequence]
      

      输出:

      [[0.4, 0.6, 0.0, 0.0], [0.2, 0.4, 0.4, 0.0], [0.0, 0.0, 0.4, 0.6]]
      

      【讨论】:

      • 硬编码太多。 /5 应替换为 /len(x)range(1,5) 应替换为 set(''.join(l))(然后您可以将 str(i) 替换为 i)。
      【解决方案4】:

      只是扩展@hiro 主角。 标记为评论的更改

      from collections import Counter
      
      lis = ['123', '134', '234', '214', '223'] 
      
      symbols = {c for s in lis for c in s} # in case you take lis as input from user
      
      percent_list = []
      
      for item in zip(*lis):
          c = Counter(item)
          total = sum(c.values())
          percent = {key: value/total for key, value in c.items()}
      
          # convert to list, 0.0 is default value
          
          percent_list.append([percent.get(i, 0.0) for i in sorted(symbols)]) # Your comment even says. But then you don't make a list you create a generator.
          
          
      sequence = list(zip(*lis))
      sorted_s = list(sorted(symbols))
      
      
      for index, item in enumerate(zip(*lis)):
          str_s_s = ','.join(sorted_s) # as pointed by @BallpointBen
          str_seque =  ' '.join(sequence[index])
          print(f"{index}th position: {str_seque} the percentage of {str_s_s} are respectively: {percent_list[index]}")
      

      提供所需的输出

      0th position: 1 1 2 2 2 the percentage of 1,2,3,4 are respectively: [0.4, 0.6, 0.0, 0.0]
      1th position: 2 3 3 1 2 the percentage of 1,2,3,4 are respectively: [0.2, 0.4, 0.4, 0.0]
      2th position: 3 4 4 4 3 the percentage of 1,2,3,4 are respectively: [0.0, 0.0, 0.4, 0.6]
      
      [Program finished] 
      

      【讨论】:

        猜你喜欢
        • 2013-12-27
        • 1970-01-01
        • 1970-01-01
        • 2014-01-29
        • 1970-01-01
        • 2017-11-12
        • 2017-03-28
        • 1970-01-01
        • 2017-10-07
        相关资源
        最近更新 更多