如何计算'for'循环中最后项目的平均值?

时间:2017-09-17 23:17:52

标签: python numpy for-loop

我有以下Python 3代码:

import random
import numpy as np
data = []
for i in range(0, 100):
    value = random.randrange(100)
    avg10 = np.average(data[:-10]['value'])
    data += [{'value': value, 'avg10': avg10}]

旨在在列表中生成100个随机数以及最后10个项的平均值。

不幸的是,代码失败了:

Traceback (most recent call last):
  File "avg_test.py", line 6, in <module>
    avg10 = np.average(data[:-10]['value'])
TypeError: list indices must be integers or slices, not str

因为我不确定如何从字典列表中访问10个最后的值项(或者如果所有10个项都不可用,则为更少的项)并将其传递给numpy的average函数。

例如,我希望输出类似于:

  

[{'value': 11, 'avg10': 11}, {'value': 62, 'avg10': 36.5}, {'value': 56, 'avg10': 43}, {'value': 48, 'avg10': 44.25}, {'value': 43, 'avg10': 41.8}]

等等。

其中avg10是相对于当前项目的最后(至少)10个项目的平均值(理想情况下包括当前项目,但不是必须的)。如果只有一个前一个元素,则它是1个元素的平均值,如果是2个 - 它是两个值项的平均值,依此类推(平均最多10个项)。

在这种情况下,正确的语法是什么?

5 个答案:

答案 0 :(得分:2)

要保留dict解决方案并避免第一个切片出现问题,您可以执行以下操作。

你的专栏:

avg10 = np.average(data[:-10]['value']) 

应该是:

avg10 = np.average([data[j]['value'] if j>=0 else value for j in range(i-10, i) ])

但这会导致您的mean不是以前10个结果的平均值,因为之前没有10个结果可用...
注意:我选择第一个值表示平均值,但第二个表示最后10个可用值,因此只有最后一个。所以前两个值都是自己的意思。这很奇怪。您可以决定使用

更改此行为

avg10 = np.average([data[j]['value'] if j>=0 else firstAverage for j in range(i-10, i) ])

如果您决定将值本身包含在平均值的最后10个内(即{value;最后9个项目的平均值和值本身}的dict),那么第一个项目(具有没有上一个项目)你可以这样做:

for i in range(0, 100):
    value = random.randrange(100)
    lasts = [data[j]['value'] for j in range(i-9, i) if j>=0]
    lasts.append(value)
    avg10 = np.average(lasts)
    data += [{'value': value, 'avg10': avg10}]

在最后一种情况下,您可以更准确地编辑问题;)

答案 1 :(得分:2)

这是一个完整的解决方案,其中平均值也考虑了当前值:

import random
import numpy as np
data = []
for i in range(0, 200):
    value = random.randrange(100)
    avg10 = np.average([x['value'] for x in data[-min(len(data), 10):]] + [value])
    data += [{'value': value, 'avg10': avg10}]

基本上np.average()接受包含要平均的数据的数组,因此需要使用list comprehensions将字典列表转换为平面列表。对于范围,-min(len(data), 10):用于获取最近10个项目或更少,具体取决于data的当前大小。

为了更容易理解上面的示例,这里是更简单的帮助程序代码:

>>> data = []
>>> for i in range(0, 10):
...     index = -min(len(data), 5)
...     data += [i]
...     print(i, index, data[index:])
... 
0 0 [0]
1 -1 [1]
2 -2 [1, 2]
3 -3 [1, 2, 3]
4 -4 [1, 2, 3, 4]
5 -5 [1, 2, 3, 4, 5]
6 -5 [2, 3, 4, 5, 6]
7 -5 [3, 4, 5, 6, 7]
8 -5 [4, 5, 6, 7, 8]
9 -5 [5, 6, 7, 8, 9]

答案 2 :(得分:0)

错误消息提供了一个很好的提示:•#34;列表索引必须是整数或切片,而不是str&#34;。换句话说,我们必须寻找一个我们使用字符串作为列表索引的地方。

data是一个dicts列表。因此,data[:-10]也是一个词典列表,这意味着data[:-10]['value']没有意义。你需要像[x['value'] for x in data[:-10]]这样的东西,迭代在dicts列表上。

答案 3 :(得分:0)

import random
import numpy as np
data = []
for i in range(0, 100):
    values = np.random.uniform(0, 100, size=100)
    value = random.randrange(100)
    avg10 = np.average(values[max(value-9,0):value+1])
    data += [{'value': value, 'avg10': avg10}]

答案 4 :(得分:0)

试试这个

import random
import numpy as np

data = []
for i in range(0, 100):
    value = random.randrange(100)
    avg10 = np.average(range(value+1)[-10:]) if value !=0 else 0
    data.append({'value': value, 'avg10': avg10})
print(data)