【问题标题】:Count values in a dict of lists and join keys and values names for the output using pandas使用 pandas 计算列表字典中的值并连接输出的键和值名称
【发布时间】:2020-09-19 00:32:57
【问题描述】:

我需要帮助从字典 (python3) 中获取一些输出:

{'horse': ['brown', 'black'], 'duck': ['brown', 'black', 'brown', 'grey', 'brown']}

需要的输出:

black horse: 1
brown horse: 1
grey horse: 0
black duck: 1
brown duck: 3
grey duck: 1

有人可以提供解决方案吗?

【问题讨论】:

    标签: python python-3.x pandas dictionary


    【解决方案1】:

    如果您只想在 Python 中执行此操作:

    您可以使用来自collections 模块的Counter

    In [622]: from collections import Counter
    In [623]: d = {'horse': ['brown', 'black'], 'duck': ['brown', 'black', 'brown', 'grey', 'brown']} 
    
    In [611]: l = [j + ' ' + key for key, value in d.items() for j in value]
    
    In [620]: Counter(l)                   
    Out[620]: 
    Counter({'brown horse': 1,
         'black horse': 1,
         'brown duck': 3,
         'black duck': 1,
         'grey duck': 1})
    

    【讨论】:

      【解决方案2】:

      我想这可以进一步优化,但你可以尝试:

      d={'horse': ['brown', 'black'], 'duck': ['brown', 'black', 'brown', 'grey', 'brown']}
      
      s=pd.Series(d).explode()
      import itertools
      l=[*map(' '.join,itertools.product(s.index.unique(),s.unique()))]
      print(s.reset_index().agg(' '.join,1).value_counts().reindex(l,fill_value=0))
      

      horse brown    1
      horse black    1
      horse grey     0
      duck brown     3
      duck black     1
      duck grey      1
      dtype: int64
      

      【讨论】:

        【解决方案3】:

        既然你标记 pandaexplode ,然后通过 crosstab 计算频率,并用 join 展平索引

        s=pd.Series(d).explode()
        s=pd.crosstab(s.index,s).stack()
        s.index=s.index.map('_'.join)
        s.to_dict()
        {'duck_black': 1, 'duck_brown': 3, 'duck_grey': 1, 'horse_black': 1, 'horse_brown': 1, 'horse_grey': 0}
        

        【讨论】:

          【解决方案4】:

          您可以使用defaultdict,默认出厂设置为整数 - 这充当字典中所有条目的计数器:

          from collections import defaultdict
          d = defaultdict(int)
          for k,v in data.items():
              for val in v:
                  #combine the key with the individual values in the list
                  #and get the tally/count
                  d[" ".join((val,k))] += 1
          
          d
          
          defaultdict(int,
                      {'brown horse': 1,
                       'black horse': 1,
                       'brown duck': 3,
                       'black duck': 1,
                       'grey duck': 1})
          

          【讨论】:

            【解决方案5】:

            您可以递归地将键的字符串附加到所需结果并记录唯一的解决方案。

            我想使用的伪代码如下:

            def helper(dict, string_of_prior_keys = ""):
              list_of_strings = []
              for k in dict.keys():
                if type(dict[k]) is dict:
                  list_of_strings += [helper(dict[k], k + string_of_prior_keys)]
                else:
                  list_of_strings += [k + string_of_prior_keys]
              return list_of_strings
            

            那么您需要做的就是计算返回的字符串列表中的唯一字符串。我希望这有帮助。如果我有任何不清楚的地方,请告诉我!

            【讨论】:

            • 请注意,这根本不是最有效的,而且它有点硬编码,因为我看到嵌套信息描述了字典的上层。
            • 即使它是一个算法,您也可以将dict[k] is dictionary 替换为type(dict[k]) is dict 只是为了清楚起见,并且不要使用内置的名称作为变量名;)
            • 当然。当我说伪代码时并没有打算编写实际代码,但没有意识到只有一行是非代码。
            猜你喜欢
            • 2020-01-31
            • 1970-01-01
            • 2017-06-06
            • 2019-10-06
            • 2016-09-13
            • 2018-03-08
            • 2021-09-22
            • 1970-01-01
            • 2021-03-15
            相关资源
            最近更新 更多