2
votes

Moyenne de chaque segment consécutif dans une liste

J'ai une liste:

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]

Je veux calculer la moyenne de tous, disons 4 éléments. Mais pas 4 éléments séparément, plutôt les 4 premiers:

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

suivi de:

3,4,5,6

suivi de: p >

2,3,4,5

et ainsi de suite.

Le résultat sera un tableau ou une liste de moyennes entre tous les 4 éléments de la première liste.

Sortie :

1,2,3,4

Ma tentative:

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

Ce n'est pas le résultat dont j'ai besoin car cela calcule la moyenne de tous les 4 éléments avant de passer à un nouvel ensemble de 4 éléments. Je veux seulement déplacer un élément vers le haut dans la liste et calculer la moyenne de ces 4 et ainsi de suite.


0 commentaires

4 Réponses :


4
votes

Vous pouvez utiliser une compréhension de liste sur une ligne:

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

Bien sûr, remplacez les crochets par des crochets ronds si vous voulez un générateur.


0 commentaires

7
votes

Si numpy est une option, un moyen simple d'y parvenir est d'utiliser np.convolve , qui peut être utilisé pour calculer une moyenne mobile lors de la convolution avec un tableau de np.ones code > :

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

Sortie

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

Détails b >

np.convolve effectue une convolution discrète entre les deux tableaux d'entrée. Dans ce cas np.ones (w) , qui sera un tableau d'autant de uns que la longueur de fenêtre spécifiée (4 dans ce cas) array ([1., 1., 1 ., 1.]) et sample_list.

La compréhension de liste suivante vise à reproduire la façon dont np.convolve calcule la sortie valeurs:

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])

Ainsi, à chaque itération, il prendra le produit interne entre le tableau de uns et la fenêtre actuelle de sample_list code>.

Ci-dessous est un exemple de la façon dont les premières sorties sont calculées pour que ce soit un peu plus clair. Notez que dans ce cas, le mode utilisé spécifié pour la convolution est valide , ce qui signifie que le chevauchement est spécifié pour être toujours complet:

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])

Et ce qui suit comme:

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

Et ainsi de suite, donnant comme mentionné précédemment une moyenne mobile de sample_list . p>


3 commentaires

Pouvez-vous expliquer ce que fait np.ones ()?


Cela a-t-il aidé @Murray? N'oubliez pas que vous pouvez voter pour / accepter si c'est le cas, voir Que dois-je faire lorsque quelqu'un répond à ma question?


Oui, cela a été très utile. La «moyenne mobile» est exactement ce que je recherchais. Approuvé et accepté. Merci beaucoup.



1
votes

Vous pouvez mapper la fonction mean () à des itérateurs compressés:

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 commentaires

0
votes

En tant que nouveau programmeur avec peu ou pas de connaissance de la plupart des modules python, voici une autre solution. 4 est le nombre de divisions. il peut toujours être ajusté autant que vous le souhaitez. Alors que 3 dans (Len (nlis) - 3) est 4 - 1. remplacez donc 3 par votre nombre de divisions - 1.

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

summation = []
ave = []
for a in range(len(nlis)- 3):
    summation = sum(nlis[a:a+4])
    ave.append(summation/4)
print(ave)

# [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 commentaires