Una serie de desafíos # 3: promedios móviles


16

Nota: Este es el n. ° 3 en una serie de desafíos de de . Para el desafío anterior, haga clic aquí .

Media móvil de una lista

El promedio móvil de una lista es un cálculo que resulta en una nueva lista suavizada, creada promediando pequeñas sublistas superpuestas del original.

Al crear un promedio móvil, primero generamos la lista de sublistas superpuestas usando un cierto 'tamaño de ventana', desplazando esta ventana hacia la derecha una vez cada vez.

Por ejemplo, dada la lista [8, 4, 6, 2, 2, 4]y el tamaño de la ventana 3, las sublistas serían:

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

Luego calculamos el promedio promedio de cada sublista para obtener el resultado: [6.0, 4.0, 3.3, 2.7](cada valor redondeado a un decimal).


El reto

Su tarea es escribir un programa o función que, dada una lista L , y un número entero 1 ≤ n ≤ longitud (L) , calcule el promedio móvil para L usando el tamaño de ventana n .

Reglas:

  • Su programa puede usar división entera o división flotante. En el caso de la división flotante, se permiten pequeñas inexactitudes debido a las limitaciones del tipo de datos, siempre que el valor sea correcto.
  • Puede enviar un programa completo o una función (pero no un fragmento).
  • Puede suponer que la lista solo contendrá enteros positivos .
  • Las lagunas estándar están prohibidas.
  • Este es el , por lo que gana la respuesta más corta (en bytes).

Casos de prueba

Tenga en cuenta que, para facilitar la lectura, todos los valores se redondean a un 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]

¿Tenemos que redondear los valores flotantes o podemos dejarlos como están?
caird coinheringaahing

3
@cairdcoinheringaahing Tenga en cuenta que, para facilitar la lectura , todos los valores se redondean a un decimal . En mi opinión, definitivamente puedes dejarlos como están (al menos eso es lo que entiendo).
Sr. Xcoder

@cairdcoinheringaahing He sido bastante liberal con E / S: los valores enteros o flotantes están bien, puede redondear si lo desea pero no tiene que hacerlo, y se permiten errores de punto flotante
FlipTack

¿Está bien devolver fracciones en lugar de números de coma flotante?
JungHwan Min

@JungHwanMin Si para mayor precisión, su idioma almacenará valores como fracciones en lugar de flotantes, está bien imprimirlos como fracciones precisas en sus formas más simples.
FlipTack

Respuestas:





7

Dyalog APL, 4 bytes

1 byte guardado gracias a @Graham

2 bytes guardados gracias a @ jimmy23013

¿Mencioné que APL no es un lenguaje de golf?

⊢+/÷

con na la derecha, o

+/÷⊣

con La la derecha.

Pruébalo en línea!

¿Cómo?

÷- dividir Lporn

⊢+/- reducir +en ventanas den


¿Por qué no dividir L por n antes de la reducción? Guarda un byte
Graham



@ jimmy23013 muchas gracias! Lo intenté antes, pero debo haber escrito mal los argumentos porque no funcionó.
Uriel

6

Python , 48 bytes

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

Pruébalo en línea!

Una función recursiva. Más corto que el programa (50 bytes)

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

Pruébalo en línea!

Esto ahorra 2 bytes al terminar con un error en la whilecondición.



4

Perl 6 , 33 bytes

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

Pruébalo

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];}

Pruébalo en línea!

Desenrollado:

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

]+/\%

Pruébalo en línea!

Toma ncomo argumento correcto y la lista como la izquierda. Gracias a la solución de Uriel por la idea de hacer solo la suma en el infijo.

Explicación

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

Solución anterior (7 bytes)

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


3

Pyth , 5 bytes

.O.:F

Pruébalo aquí!

Como funciona esto

.O.: F - Programa completo.

    F - Reduzca la entrada (lista anidada) con ...
  .: - ... Sublistas.
.O - Promedio de cada uno.

3

Octava , 33 31 bytes

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

Pruébalo en línea!

Explicación

La convolución ( conv) es esencialmente una suma ponderada móvil. Si los pesos se eligen como [1/n, ..., 1/n](obtenidos como ~~(1:n)/n), el resultado es un promedio móvil, del cual solo 'valid'se conserva la parte.


2

R , 72 bytes

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

Pruébalo en línea!

Calcula el meande todas las nventanas de tamaño ; cuando la ventana pasa el borde de l, los resultados son NAasí que los filtramos.

Paquete R + zoo, 13 bytes

zoo::rollmean

El zoopaquete (infraestructura S3 para series temporales regulares e irregulares) tiene muchas funciones útiles. Puedes probarlo aquí (R-fiddle) .


2

Japt v2.0a0, 7 bytes

ãV ®x÷V

Intentalo


Explicación

Entrada implícita de matriz Uy entero V.

ãV

Obtener subsecciones de Ucon longitudV

®

Mapa sobre las subsecciones.

÷V

Divide cada elemento entre V.

x

Suma todos los elementos.




1

05AB1E , 5 bytes

ŒsùÅA

Explicación:

Œ     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.

Pruébalo en línea!



1

Protón , 46 bytes

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

Pruébalo en línea!

Tenga en cuenta que esto toma datos a través de la sintaxis de las funciones de curry y devuelve una lista de fracciones.



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

Pruébalo en línea!


0

JavaScript (ES6), 53 bytes

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





0

K (oK) , 13 11 bytes

Solución:

{+/+x':y%x}

Pruébalo en línea!

Ejemplos:

{+/+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

Explicación:

oK tiene una función integrada para crear una ventana deslizante, luego resume las matrices resultantes y divide por tamaño de ventana deslizante para obtener el significado:

{+/+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 no necesita el flip array +, y si K se ha desplazado como APL, puede moverse x%[commute]hacia la izquierda y soltar los parens
Uriel

La inversión es necesaria para garantizar que la suma esté en lugar de en cada lista, y bastante seguro de que no hay un operador de viaje, al menos nada que lo sugiera en el manual . Saludos sin embargo!
Calles

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;}

Explicación:

Pruébalo aquí

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.