字典列表中值子集的平均值

Average value of subset of values in a list of dictionaries

我有一个字典列表。我想要25岁以下人群的平均年龄

我知道我的除数是错误的,但我不确定如何在理解范围内调整它。

我得到 81/8 = 10.125。我应该得到 81/5 = 16.2。如何获得除数以匹配添加的元素数?

people = [{'name': 'John', 'age': 47, 'hobbies': ['Python', 'cooking', 'reading']},
          {'name': 'Mary', 'age': 16, 'hobbies': ['horses', 'cooking', 'art']},
          {'name': 'Bob', 'age': 14, 'hobbies': ['Python', 'piano', 'cooking']},
          {'name': 'Sally', 'age': 11, 'hobbies': ['biking', 'cooking']},
          {'name': 'Mark', 'age': 54, 'hobbies': ['hiking', 'camping', 'Python', 'chess']},
          {'name': 'Alisa', 'age': 52, 'hobbies': ['camping', 'reading']},
          {'name': 'Megan', 'age': 21, 'hobbies': ['lizards', 'reading']},
          {'name': 'Amanda', 'age': 19, 'hobbies': ['turtles']},
          ]


print(float(sum(d['age'] for d in people if d['age'] < 25)) / len(people))

与其在一个列表理解中完成所有操作,我将其分成两个命令,如下所示:

>>> under_25 = [x['age'] for x in people if x['age'] < 25]
>>> avg_age = sum(under_25)/float(len(under_25))

在一个列表理解中执行所有这些操作需要您执行两次(一次计算分子中的总和,另一次计算分母中的长度)。我认为这也更具可读性。

您甚至可以尝试在 for 循环中执行此操作:

count = 0
s = 0
for person in people:
    if person['age'] < 25:
        s += person['age']
        count += 1
avg_age = float(s)/count

最简单的解决方案是使用 numpy 和条件列表理解:

import numpy as np

>>> np.mean([p['age'] for p in people if 'age' in p and p['age'] < 25])
16.199999999999999

使用纯 python 解决方案,您应该在评估集合中的每个元素时跟踪总数和计数。这减少了内存占用,因为您不需要存储所有符合条件的值。请注意,我在枚举中使用了生成器。

total_age = 0.
for n, age in enumerate((p['age'] for p in people if 'age' in p and p['age'] < 25), start=1):
    total_age += age
>>> print(total_age / n)
16.2

Python 有一个 statistics module that contains a mean 函数:

>>> from statistics import mean
>>> mean(d['age'] for d in people if d['age'] < 25)
16.2

或者,如果您有 pandas,您可以使用布尔索引:

>>> import pandas as pd

>>> df = pd.DataFrame(people, columns=['name', 'age', 'hobbies'])
>>> df[df['age'] < 25]['age'].mean()
16.2

df[df['age'] < 25] 仅包含那些年龄低于 25 岁的行,然后 ['age'].mean() 计算 "age" 列的平均值。