【问题标题】:Calculating frequency of items in a dictionary计算字典中项目的频率
【发布时间】:2019-11-27 01:13:57
【问题描述】:

我有一个名为 purchases 的字典,它以付款方式作为键,而字典则包含付款类型及其频率作为值。示例格式如下:

{'Credit card': {'Grocery': 3, 'Gas': 1, 'Store': 2},
'Debit card': {'Food': 2},
'Check': {'Rent': 1, 'Utilities': 1}, … }

我想创建一个新字典,其中支付方式的频率作为键,支付方式作为值。期望的输出:

[{6: ['Credit card']}, {2: ['Debit card', 'Check']}]

到目前为止,这是我的代码:

artist_count = {}
for artist in artist_songs.keys():
    if artist in artist_count:
        artist_count[artist] += 1
    else:
        artist_count[artist] = 1
print(artist_count)

目前,这会输出一个字典,其中每个唯一的付款方式作为键,1 作为其值。我很难计算每个的频率,以及切换键和值。 (我相信我可以将 len 函数用于前者,但我还没有运气。)

如何创建以支付方式频率为键、支付方式为值的新字典?

【问题讨论】:

  • 请提出一个真正的问题。提前致谢。
  • @PeterMortensen 刚刚编辑了它。
  • 您必须先计算付款方式的频率。一旦你有了它,你可以循环这些值并填充一个新字典,如果存在频率,你将付款添加到它的列表中,否则你将一个新项目添加到具有新频率的字典和具有单一付款方式的列表中。希望这会有所帮助。
  • 您真的希望支付方式的频率作为关键吗?我没有看到一个好的用例。您不希望将付款方式保留为键,但使用 key=payment method 和 value=frequency 的新字典?
  • 您想要一个列表或字典作为所需的输出吗?你写了 dict,但你的例子是一个列表。我编辑了你的问题,假设它是一个 dict 作为所需的输出,但你同样可以编辑问题的文本以要求一个列表作为输出。

标签: python dictionary python-3.6


【解决方案1】:

让我们分两步完成:

  1. 我们首先制作一个字典,其中键是支付类型,值是频率。
  2. 然后,我们将这个字典逆序得到你想要的字典。

对于第一部分,

freq_dict = {}
for key in given_dict:
    freq_dict[key] = 0
    for item in given_dict[key]:
        freq_dict[key]+=given_dict[key][item]

第二部分:

result_dict = {}
for key in freq_dict:
    value = freq_dict[key]
    if value not in result_dict:
        result_dict[value] = []
    result_dict[value].append(key) 

given_dict 是我们开始使用的字典。

如果有不清楚的地方请告诉我:)

【讨论】:

    【解决方案2】:
    purchases = {'Credit card': {'Grocery': 3, 'Gas': 1, 'Store': 2},
    'Debit card': {'Food': 2}, 'Check': {'Rent': 1, 'Utilities': 1}}
    
    paymentFreq = {}
    
    for method, category in purchases.items():
        countSum = 0
        for item, count in category.items():
            countSum = countSum + count
        if countSum not in paymentFreq:
            paymentFreq[countSum] = [method]
        else:
            paymentFreq[countSum].append(method)
    
    print(paymentFreq)
    

    【讨论】:

      【解决方案3】:

      在 pandas 中也可以这样:

      df = pd.DataFrame({'vals':[*in_dict.values()],'vars':[*in_dict.keys()]})
      df['vals'] = df['vals'].apply(lambda x: sum(x.values())) #because nested dict
      out_dict = df.groupby('vals')['vars'].agg(list).to_dict()
      

      输出:

      {2: ['Debit card', 'Check'], 6: ['Credit card']}
      

      【讨论】:

      • 这是最短且唯一的矢量化解决方案,这应该是公认的答案:)
      【解决方案4】:

      我的解决方案遵循与@Shagun Sodhani 相同的逻辑,但使用一个循环而不是两个循环

      payments = {'Credit card': {'Grocery': 3, 'Gas': 1, 'Store': 2},
      'Debit card': {'Food': 2},
      'Check': {'Rent': 1, 'Utilities': 1}}
      
      sums = {}
      
      for payment_type, payment_entries in payments.items():
          # calculate the number of times that a payment was used
          payment_type_frequency = sum(payment_entries.values())
      
          # check if the frequencu is already in the result array
          if payment_type_frequency in sums.keys():
              # if yes, append
              sums[payment_type_frequency].append(payment_type)
          else:
              # else add a new key and assign a one element list to it
              sums[payment_type_frequency] = [payment_type]
      
      print(sums)
      

      我们也可以使用 defaultdict 来简化这段代码:

      import collections 
      
      payments = {'Credit card': {'Grocery': 3, 'Gas': 1, 'Store': 2},
      'Debit card': {'Food': 2},
      'Check': {'Rent': 1, 'Utilities': 1}}
      
      sums = collections.defaultdict(list)
      
      for payment_type, payment_entries in payments.items():
          # calculate the number of times that a payment was used
          payment_type_frequency = sum(payment_entries.values())
          # check if the frequency is already in the result array
          sums[payment_type_frequency].append(payment_type)
      
      print(sums)
      

      或者我们也可以使用列表推导来获得更智能但不可读的代码(在任何生产代码中都没有建议):

      import collections 
      
      payments = {'Credit card': {'Grocery': 3, 'Gas': 1, 'Store': 2},
      'Debit card': {'Food': 2},
      'Check': {'Rent': 1, 'Utilities': 1}}
      
      sums = collections.defaultdict(list)
      
      [sums[sum(payment_entries.values())].append(payment_type) for payment_type, payment_entries in payments.items()]
      
      print(sums)
      

      【讨论】:

        【解决方案5】:

        一种简单的方法是在此处使用列表中的collections.defaultdict 按总和进行分组并附加付款方式:

        from collections import defaultdict
        
        data = {
            "Credit card": {"Grocery": 3, "Gas": 1, "Store": 2},
            "Debit card": {"Food": 2},
            "Check": {"Rent": 1, "Utilities": 1},
        }
        
        payment_map = defaultdict(list)
        for method, payments in data.items():
            total = sum(payments.values())
            payment_map[total].append(method)
        
        print([{k: v} for k, v in payment_map.items()])
        # [{6: ['Credit card']}, {2: ['Debit card', 'Check']}]
        

        在此处使用 defaultdict 的好处是,它会在添加新密钥时自动为您创建列表。你不必自己做,这也会导致代码更简洁。

        如果您更喜欢非库解决方案,您可以在此处使用dict.setdefault()

        payment_map = {}
        for method, payments in data.items():
            total = sum(payments.values())
            payment_map.setdefault(total, []).append(method)
        

        注意: How does collections.defaultdict work? 是一个很好的问题,可以探索有关 defaultdict 工作原理的更多信息。

        【讨论】:

          【解决方案6】:

          如果熊猫是一个选项,试试这个:

          import pandas as pd
          import collections
          
          mycounter=[]
          dff = {'Credit card': {'Grocery': 3, 'Gas': 1, 'Store': 2},'Debit card': {'Food': 2},'Check': {'Rent': 1, 'Utilities': 1}}
          
          newdf2 = pd.read_json(json.dumps(dff))
          for i,j in newdf2.iteritems():
              mycounter.append({ newdf2[i].sum().astype(int) :[i]})
          
          res = {}
          for d in mycounter:
              for k, v in d.items():
                  res.setdefault(k, []).extend(v)
          
          res
          #[{6: ['Credit card']}, {2: ['Debit card', 'Check']}]
          
          
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-01-12
            • 2015-02-21
            • 1970-01-01
            • 2022-07-16
            • 2018-05-30
            • 1970-01-01
            相关资源
            最近更新 更多