【问题标题】:How to group tuples by common items and find average per each group如何按常见项目对元组进行分组并找到每组的平均值
【发布时间】:2017-05-24 14:19:53
【问题描述】:

我有一个名为 data 的元组列表:

data = [('A', 2), 
        ('B', 2), ('B', 4), ('B', 6), ('B', 8), ('B', 6), ('B', 4), ('B', 3),
        ('C', 10), ('C', 10), ('C', 10),
        ('D', 12),
        ('E', 12),
        ('F', 10), ('F', 8), ('F', 6)]
average = []

我想要每个相同字母的平均值:

预期输出:

average = [('A', 2), ('B', 5), ('C', 10), ('D', 12), ('E', 12), ('F', 8)]

【问题讨论】:

  • 您应该查看字典而不是这样使用元组。它们保存键/值对,让您找到某些键的值。
  • 我创建了另一个数组,计算每个字母 count=[1,7,3,1,1,3] 然后为每个 1 获取索引并将其附加到列表中,但对于其余的数字我对使用索引感到头疼......我是编程新手

标签: python list tuples average


【解决方案1】:

这是一个带有默认字典的选项:

from collections import defaultdict
avg = defaultdict(lambda :{'count': 0, 'sum': 0})
​
# calculate the sum and count for each key
for k, v in data:
    avg[k]['count'] += 1
    avg[k]['sum'] += v

# calculate the average
[(k, v['sum']/v['count']) for k, v in avg.items()]

#[('A', 2.0),
# ('D', 12.0),
# ('F', 8.0),
# ('E', 12.0),
# ('B', 4.714285714285714),
# ('C', 10.0)]

【讨论】:

  • 为什么是嵌套字典?只需将数字存储在列表中并执行sum(v)/len(v)
  • @tobias_k 您将需要额外的空间来存储数字,而且,sum/len 意味着需要第二个循环。我认为移动计算应该更有效。
  • 值得注意的是,这个解决方案比itertools.groupby更通用,因为它是O(n),不需要对输入进行预排序。
【解决方案2】:

试试groupby

from itertools import groupby
data_ = [(n,[i[1] for i in g]) for n,g in groupby(data, key = lambda x:x[0])]   
result = [(i,float(sum(j))/float(len(j))) for i,j in data_]

结果

[('A', 2.0),
 ('B', 4.714285714285714),
 ('C', 10.0),
 ('D', 12.0),
 ('E', 12.0),
 ('F', 8.0)]

【讨论】:

    【解决方案3】:

    您可能会考虑使用pandas 的替代解决方案,尤其是在处理大型数据集时。在这里,groupby and mean 将完成这项工作:

    import pandas as pd
    
    data = [('A', 2), 
            ('B', 2), ('B', 4), ('B', 6), ('B', 8), ('B', 6), ('B', 4), ('B', 3),
            ('C', 10), ('C', 10), ('C', 10),
            ('D', 12),
            ('E', 12),
            ('F', 10), ('F', 8), ('F', 6)]
    
    df = pd.DataFrame(data, columns=['letter', 'number'])
    print(df)
    #    letter  number
    # 0       A       2
    # 1       B       2
    # 2       B       4
    # 3       B       6
    # 4       B       8
    # 5       B       6
    # 6       B       4
    # 7       B       3
    # 8       C      10
    # 9       C      10
    # 10      C      10
    # 11      D      12
    # 12      E      12
    # 13      F      10
    # 14      F       8
    # 15      F       6
    
    print(df.groupby('letter').mean())
    #            number
    # letter           
    # A        2.000000
    # B        4.714286
    # C       10.000000
    # D       12.000000
    # E       12.000000
    # F        8.000000
    
    print(df.groupby('letter').mean().round().astype(int))
    #         number
    # letter        
    # A            2
    # B            5
    # C           10
    # D           12
    # E           12
    # F            8
    

    您可以按如下方式取回您的元组列表:

    averages = df.groupby('letter').mean().round().astype(int)
    result = list(result.to_records())
    print(result)
    # [('A', 2), ('B', 5), ('C', 10), ('D', 12), ('E', 12), ('F', 8)]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-06
      • 1970-01-01
      • 2022-11-16
      • 1970-01-01
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      • 2021-01-31
      相关资源
      最近更新 更多