Среднее каждого последовательного сегмента в списке - PullRequest
0 голосов
/ 10 февраля 2019

У меня есть список:

sample_list = array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])

Я хочу вычислить среднее значение каждого, скажем, 4 элемента.Но не 4 элемента по отдельности, а первые 4:

1,2,3,4

, затем:

2,3,4,5

, затем:

3,4,5,6

и т. Д.

Результатом будет массив или список средних значений для каждых 4 элементов в первом списке.

Вывод:

array([2.5, 3.5, 4.5, ...])

Моя попытка:

sample_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
splits = 4

def avgerage_splits(data):
    datasum = 0
    count = 0 
    for num in data:
        datasum += num
    count += 1
    if count == splits: 
        yield datasum / splits
        datasum = count = 0
if count: 
    yield datasum / count

print(list(average_splits(sample_list)))

[1.5, 3.5, 5.5, 7.5, 9.5, 11.0]

Это не тот вывод, который мне нужен, так как он вычисляет среднее значение для каждых 4 элементов перед переходом на новый набор из 4 элементов.Я хочу переместить только один элемент вверх в списке и вычислить среднее значение этих 4 и т. Д.

Ответы [ 3 ]

0 голосов
/ 10 февраля 2019

Если numpy является опцией, простой способ достижения этого состоит в использовании np.convolve, который можно использовать для вычисления скользящего среднего при свертке с массивомnp.ones:

import numpy as np
sample_list = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], dtype=float)

w = 4
np.convolve(sample_list, np.ones(w), 'valid') / w

Выход

array([ 2.5,  3.5,  4.5,  5.5,  6.5,  7.5,  8.5,  9.5, 10.5, 11.5, 12.5,
   13.5, 14.5])

Подробности

np.convolve выполняет дискретную свертку между двумя входными массивами.В этом случае np.ones(w), который будет массивом, равным указанной длине окна (в данном случае 4) array([1., 1., 1., 1.]) и sample_list.

Следующее понимание списка имеет целью повторить способnp.convolve вычисляет выходные значения:

w = 4
np.array([sum(ones*sample_list[m:m+w]) for m in range(len(sample_list)-(w-1))]) / w 

array([ 2.5,  3.5,  4.5,  5.5,  6.5,  7.5,  8.5,  9.5, 10.5, 11.5, 12.5,
   13.5, 14.5])

Таким образом, на каждой итерации он будет принимать внутреннее произведение между массивом единиц и текущим окном из sample_list.

Ниже приведен пример того, как первые результаты вычисляются так, чтобы он был немного понятнее.Обратите внимание, что в этом случае используемый режим, указанный для свертки, равен valid, что означает, что перекрытие определяется как всегда завершенное:

[1,1,1,1]
[1,2,3,4,5,6,7,8...]
= (1*1 + 1*2 + 1*3 + 1*4) / 4 = 2.5

И следующее как:

  [1,1,1,1]
[1,2,3,4,5,6,7,8...]
= (1*2 + 1*3 + 1*4 + 1*5) / 4 = 3.5

И так далее, получая, как упоминалось ранее, скользящее среднее из sample_list.

0 голосов
/ 11 февраля 2019

Вы можете сопоставить функцию mean() с заархивированными итераторами:

from statistics import mean
from itertools import islice

l = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]

zip_iter = zip(*(islice(l, i, None) for i in range(4)))
list(map(mean, zip_iter))
# [2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5]
0 голосов
/ 10 февраля 2019

Вы можете использовать понимание списка в одну строку:

avgs = [sum(sample_list[i:i + splits]) / splits for i in range(len(sample_list) - splits + 1)]

Конечно, замените квадратные скобки круглыми скобками, если вы хотите генератор.

...