Uma série de desafios # 3: médias móveis


16

Nota: Este é o número 3 em uma série de desafios de de . Para o desafio anterior, clique aqui .

Média Móvel de uma Lista

A média móvel de uma lista é um cálculo que resulta em uma nova lista suavizada, criada pela média de pequenas sublistas sobrepostas do original.

Ao criar uma média móvel, primeiro geramos a lista de sublistas sobrepostas usando um certo 'tamanho da janela', deslocando essa janela para a direita uma vez a cada vez.

Por exemplo, dada a lista [8, 4, 6, 2, 2, 4]e o tamanho da janela 3, as sublistas seriam:

[8,  4,  6,  2,  2,  4]          Sublists:
(         )                  <-  [8, 4, 6]
    (         )              <-  [4, 6, 2]
        (         )          <-  [6, 2, 2]
            (         )      <-  [2, 2, 4]

Em seguida, calculamos a média média de cada sub-lista para obter o resultado: [6.0, 4.0, 3.3, 2.7](cada valor arredondado para uma casa decimal).


O desafio

Sua tarefa é escrever um programa ou função que, dada uma lista L e um número inteiro 1 ≤ n ≤ length (L) , calcule a média móvel de L usando o tamanho da janela n .

Regras:

  • Seu programa pode usar divisão inteira ou divisão flutuante. No caso da divisão de flutuação, pequenas imprecisões devido às limitações do tipo de dados são permitidas, desde que o valor esteja correto.
  • Você pode enviar um programa completo ou uma função (mas não um trecho).
  • Você pode assumir que a lista conterá apenas números inteiros positivos .
  • As brechas padrão são proibidas.
  • Isso é , então a resposta mais curta (em bytes) vence!

Casos de teste

Observe que, para facilitar a legibilidade, todos os valores são arredondados para uma casa decimal.

n=5, [1, 2, 3, 4, 5, 6, 7, 8]      ->      [3, 4, 5, 6]
n=3, [100, 502, 350, 223, 195]     ->      [317.3, 358.3, 256]
n=1, [10, 10, 10]                  ->      [10, 10, 10]
n=3, [10, 20, 30]                  ->      [20]
n=2, [90, 40, 45, 100, 101]        ->      [65, 42.5, 72.5, 100.5]

Temos que arredondar valores flutuantes ou podemos deixá-los como estão?
caird coinheringaahing

3
@cairdcoinheringaahing Observe que, para facilitar a legibilidade , todos os valores são arredondados para uma casa decimal . Na minha opinião, você pode definitivamente deixá-los como estão (pelo menos é o que eu entendo).
Xcoder

@cairdcoinheringaahing Estive bastante liberal com I / O: integer ou float valores são bons, você pode rodada se quiser, mas não tem que, e os erros de ponto flutuante são permitidos
FlipTack

Tudo bem retornar frações em vez de números de ponto flutuante?
JungHwan Min

@JungHwanMin Se, para precisão, seu idioma armazenar valores como frações, e não como flutuadores, é bom imprimi-los como frações precisas em suas formas mais simples.
FlipTack

Respostas:




7

Haskell , 47 bytes

n!a|length a<n=[]|_:t<-a=div(sum$take n a)n:n!t

Experimente online!

Economizou dois bytes graças ao xnor!


1
tail apode ser extraído na guarda.
Xnor

Gah, eu sabia que estava faltando algo assim. Obrigado!
Lynn

7

Dyalog APL, 4 bytes

1 byte salvo graças a @Graham

2 bytes salvos graças a @ jimmy23013

Eu mencionei que o APL não é uma linguagem de golfe?

⊢+/÷

com nà direita, ou

+/÷⊣

com Là direita.

Experimente online!

Quão?

÷- dividir Lporn

⊢+/- reduzir +nas janelas den


Por que não dividir L por n antes da redução. Salva um byte
Graham



@ jimmy23013 muito obrigado! Eu tentei isso antes, mas deve ter digitado os argumentos errado, porque não funcionou.
Uriel

6

Python , 48 bytes

f=lambda n,l:l[n-1:]and[sum(l[:n])/n]+f(n,l[1:])

Experimente online!

Uma função recursiva. Mais curto que o programa (50 bytes)

n,l=input()
while l[-n]:print sum(l[:n])/n;l=l[1:]

Experimente online!

Isso economiza 2 bytes, encerrando com erro na whilecondição.



4

Perl 6 , 33 bytes

{@^a.rotor($^b=>1-$b)».sum X/$b}

Teste-o

Expandido:

{  # bare block with placeholder parameters 「@a」, 「$b」

  @^a                # declare and use first param

  .rotor(            # split it into chunks
    $^b              # declare and use second param
    =>               # pair it with
    1 - $b           # one less than that, negated

  )».sum             # sum each of the sub lists

  X/                 # cross that using &infix:«/»

  $b                 # with the second param
}

4

C,  86   84  83 bytes

i,j,s;f(a,l,n)int*a;{for(i=-1;i+++n<l;s=!printf("%d ",s/n))for(j=n;j--;)s+=a[i+j];}

Experimente online!

Desenrolado:

i, j, s;
f(a, l, n)int*a;
{
    for(i=-1; i+++n<l; s=!printf("%d ", s/n))
        for(j=n; j--;)
            s += a[i+j];
}

4

J, 7 5 bytes

]+/\%

Experimente online!

Toma ncomo argumento certo e a lista como esquerda. Agradecemos a solução de Uriel pela idéia de fazer apenas a soma no infix.

Explicação

]+/\%
    %  Divide list by n
]+/\   Sum on overlapping intervals of size n

Solução anterior (7 bytes)

(+/%#)\
      \  Apply to overlapping intervals of size n
(+/%#)   Mean
 +/        Sum
   %       Divided by
    #      Length



3

Oitava , 33 31 bytes

@(x,n)conv(x,~~(1:n)/n,'valid')

Experimente online!

Explicação

Convolução ( conv) é essencialmente uma soma ponderada móvel. Se os pesos são escolhidos como [1/n, ..., 1/n](obtidos como ~~(1:n)/n), o resultado é uma média móvel, da qual apenas a 'valid'parte é mantida.


2

R , 72 bytes

function(l,n)(k=sapply(0:sum(l|1),function(x)mean(l[x+1:n])))[!is.na(k)]

Experimente online!

Calcula meantodas as njanelas de tamanho ; quando a janela ultrapassa a borda l, os resultados são NAfiltrados.

Pacote zoológico R +, 13 bytes

zoo::rollmean

O zoopacote (infraestrutura S3 para séries temporais regulares e irregulares) tem muitas funções úteis. Você pode tentar aqui (violino R) .


2

Japt v2.0a0, 7 bytes

ãV ®x÷V

Tente


Explicação

Entrada implícita de matriz Ue número inteiro V.

ãV

Obter subseções de Ucom comprimentoV

®

Mapa sobre as subseções.

÷V

Divida cada elemento por V.

x

Soma todos os elementos.




1

05AB1E , 5 bytes

ŒsùÅA

Explicação:

Π    All substrings
 sù   Keep those only where the length is equal to <the second input>
   ÅA Arithmetic mean of each element in the resulting array.

Experimente online!



1

Próton , 46 bytes

n=>l=>[sum(l[h to h+n])/n for h:0..len(l)-n+1]

Experimente online!

Observe que isso recebe a entrada através da sintaxe das funções de curry e retorna uma lista de frações.



0

Jq 1.5 , 61 bytes

def f(N;L):[L|range(0;1+length-N)as$i|.[$i:$i+N]|add/length];

Expandido

def f(N;L):
  [   L
    | range(0;1+length-N) as $i        # generate
    | .[$i:$i+N]                       # sublists
    | add/length                       # compute mean
  ];

Experimente online!


0

JavaScript (ES6), 53 bytes

(l,n)=>l.map(e=>(s+=e-=a[i-n]||0)/n,s=i=0).slice(n-1)

0

PHP, 94 bytes

function f($l,$n){while($i<=count($l)-$n)$r[]=array_sum(array_slice($l,$i++,$n))/$n;return$r;}

Experimente online!





0

K (oK) , 13 11 bytes

Solução:

{+/+x':y%x}

Experimente online!

Exemplos:

{+/+x':y%x}[3;8 4 6 2 2 4]
6 4 3.3333 2.6667
{+/+x':y%x}[5;1 2 3 4 5 6 7 8]
3 4 5 6

Explicação:

oK possui um built-in para criar uma janela deslizante e, em seguida, some as matrizes resultantes e divida pelo tamanho da janela deslizante para obter uma média:

{+/+x':y%x} / the solution
{         } / lambda function taking x and y as implicit parameters
       y%x  / y (list) by x (sliding array size)
    x':     / sliding window of size x over list y
   +        / flip array (rotate by 90 degrees)
 +/         / sum up array

Parece que você não precisa a matriz aleta +, e se K tem comutar como APL você pode mover x%[commute]para a esquerda e solte os parênteses
Uriel

O flip é necessário para garantir que a soma esteja do outro lado da lista, e não abaixo de cada lista, e com certeza não há operador de deslocamento, pelo menos nada para sugerir isso no manual . Cheers embora!
Streetster

0

DataWeave , 50 bytes

fun s(l,w)=0 to(sizeOf(l)-w)map avg(l[$ to $+w-1])
%dw 2.0
output application/json

fun sma(list: Array<Number>, window: Number) =
  0 to (sizeOf(list) - window)  // generate starting indices of sublists
  map list[$ to $ + window - 1] // generate sublists
  map avg($)                    // calculate averages

---
sma([90, 40, 45, 100, 101], 2)


0

Java 8, 111 bytes

a->n->{int l=a.length-n+1,i=0,j;float[]r=new float[l];for(;i<l;r[i++]/=n)for(j=i;j<i+n;r[i]+=a[j++]);return r;}

Explicação:

Experimente aqui.

a->n->{                 // Method with array and int parameters and float-array return-type
  int l=a.length-n+1,   //  New length of the return-array
      i=0,j;            //  Index-integers
  float[]r=new float[l];//  Return-array
  for(;i<l;             //  Loop (1) from 0 to `l` (exclusive)
      r[i++]/=n)        //    After every iteration, divide the current item by input `n`
    for(j=i;j<i+n;      //   Inner loop (2) from `i` to `i+n` (exclusive)
      r[i]+=a[j++]      //    Sum the result at index `i` with the items of the input-array
    );                  //   End of inner loop (2)
                        //  End of loop (1) (implicit / single-line body)
  return r;             //  Return the resulting float-array
}                       // End of method
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.