Wednesday 18 October 2017

Límite Medio Móvil


Skip () no está optimizado para IListltTgt. Siempre enumera los elementos omitidos. Esto significa que su algoritmo es O (n 2) por ninguna buena razón. Lo que debe hacer en su lugar es iterar manualmente sólo la parte requerida de la entrada en cada iteración usando para. Algo así como: (No me gusta usar GetRange () para esto, como en la respuesta de tinstaafls, porque innecesariamente copia el marco en una nueva lista.) Si frameSize es grande, otra optimización sería no recalcular la suma del marco para cada índice. En su lugar, sólo tiene que añadir el elemento desde el frente y restar el elemento de la parte posterior: Si la longitud de los datos es n y frameSize es f. Entonces el algoritmo anterior sería O (fn), pero el mejorado sólo O (n). Otra cosa: por lo general no hay necesidad de crear tipos que derivan de List. Sólo use ListltPointPairgt directamente. Para obtener un rendimiento asintótico de O (n) (como la solución codificada manualmente), puede utilizar la función Agregado como en El valor acumulado (implementado como tipo anónimo) contiene dos campos: Resultado contains La lista de resultados se ha acumulado hasta ahora. El trabajo contiene los últimos elementos del período-1. La función de agregado agrega el valor actual a la lista de trabajo, genera el promedio actual y lo agrega al resultado y, a continuación, elimina el primer valor (es decir, el más antiguo) de la lista de trabajo. La semilla (es decir, el valor inicial para la acumulación) se construye poniendo los primeros elementos del período-1 en Trabajo e inicializando Resultado en una lista vacía. En consecuencia, la agregación comienza con el período de elemento (saltando los elementos del período-1 al principio). En la programación funcional, este es un patrón de uso típico para la función de agregado (o pliegue), btw. La solución no es funcionalmente limpia en que los mismos objetos de lista (Trabajo y Resultado) se reutilizan en cada paso. Im no seguro si eso podría causar problemas si algunos compiladores futuros intentan paralelizar la función del agregado automáticamente (por otra parte Im también no seguro, si eso es posible después de todos.). Una solución puramente funcional debería crear nuevas listas en cada paso. También tenga en cuenta que C carece de poderosas expresiones de lista. En algún pseudocódigo hipotético Python-C-mixed se podría escribir la función de agregación como la que sería un poco más elegante en mi humilde opinión :) Note el tiempo de ejecución de O (n2). Ya que es necesario saltar más y más elementos en cada paso (y afaik Skip (i) tiene que llamar IEnumerator. MoveNext i veces). Vea mi respuesta para una solución en O (n) tiempo. (Acabo de notar el comentario OPs abajo que él / ella posiblemente obtener los valores de un DB de SQL en el futuro. En este caso, yo cada fuertemente desalentar de esta solución) ndash MartinStettner Mar 3 11 at 0:53 Para los más eficientes En lugar de eso propongo crear una clase auxiliar que calcula un promedio móvil de la manera más eficiente posible (utilizando un buffer circular y un filtro de media móvil causal), luego un método de extensión para hacer Es accesible a LINQ. En primer lugar, el promedio móvil Esta clase proporciona una implementación muy rápida y ligera de un filtro MovingAverage. Crea un buffer circular de Longitud N y calcula una suma, una substracción y una multiplicación por punto de datos agregado, en contraposición a las N multiplicaciones por punto para la implementación de la fuerza bruta. Los métodos de extensión anteriores envuelven la clase MovingAverage y permiten su inserción en una secuencia IEnumerable. Para hacer esto de una manera más funcional, necesitará un método Scan que existe en Rx pero no en LINQ. Echemos un vistazo a cómo sería si tuviéramos un método de escaneo Y luego el método de escaneo, tomado y ajustado desde aquí: Esto debería tener un mejor rendimiento que el método de fuerza bruta ya que estamos usando un total de ejecución para calcular el SMA. Para empezar necesitamos calcular el primer período que llamamos semilla aquí. Luego, cada valor posterior se calcula a partir del valor de la semilla acumulada. Para hacer eso necesitamos el valor antiguo (que es t-delta) y el valor más nuevo para el cual juntamos la serie, una vez desde el principio y una vez desplazada por el delta. Al final hacemos una limpieza agregando ceros para la longitud del primer período y añadiendo el valor inicial de la semilla. Respondió Jun 19 13 a las 22: 58Tengo una cantidad de 4000 datos de la población, y tring para calcular el promedio móvil para todos los valores de datos, pero como la media móvil se basa en datos anteriores y no puedo calcular la SMA de 15 días para la primera 14 días, omita los primeros 14 días y calcule el SMA en el resto de los datos. Y tiene que estar usando LINQ para lograrlo. ¿Puede alguien dar una muestra o sugerencia de cómo utilizar LINQ para calcular el promedio móvil La salida de los valores promedio son alrededor de 500s realmente no entiendo cómo es posible obtener ese valor alto. Promedio móvil con la matriz de sumas: 06/07/2012 562,49 571,72 06/08/2012 565,84 580,32 06/11/2012 568,56 571,17 06/12/2012 569,55 576,16 13/06/2012 570,56 572,16 14/06/2012 570,63 571,53 06 / 15/2012 571,21 574,13 18/06/2012 572,78 585,78 19/06/2012 573,79 587,41 20/06/2012 574,23 585,74 21/06/2012 574,22 577,67 22/06/2012 575,63 582,10 25/06/2012 576,06 570,77 06/26 / 2012 576,68 572,03 27/06/2012 576,88 574,50 28/06/2012 576,7 569,05 29/06/2012 576,95 584,00 07/02/2012 578,37 592,52 07/03/2012 579,92 599,41 07/03/2012 581,74 599,41 Editado por Leemx Friday , 16 de noviembre de 2012 2:59 AM Movido por Lisa Zhu Lunes 19 de noviembre de 2012 7:38 AM linq related (De: Visual C General) viernes, 16 de noviembre de 2012 2:42 Para crear una media móvil , Empezaría por crear un rango de 0 a (longitud de la lista de datos - duración del período de movimiento), luego para cada valor en el rango seleccionar elementos x a x 43 longitud del período en movimiento y calcular el promedio. Todo en una declaración LINQ agradable: Tenga en cuenta que esto no es muy eficiente, ya que básicamente iterar sobre la lista de datos para cada valor en el rango .. Hey, mira Este sistema permite firmas de más de 60 cha Editado por Arno Brouwer Viernes, Noviembre 23, 2012 4:42 PM Marcado como respuesta por Alexander Sun Viernes, 07 de diciembre de 2012 2:44 Viernes, 23 de noviembre de 2012 4:41 PM Todas las respuestas Una muestra de su declaración LINQ ayudaría. Para crear un promedio móvil, comenzaría creando un rango de 0 a (longitud de la lista de datos - longitud del período móvil), luego para cada valor en el rango seleccionar elementos x A x 43 la duración del período en movimiento y calcular el promedio. Todo en una declaración LINQ agradable: Tenga en cuenta que esto no es muy eficiente, ya que básicamente iterar sobre la lista de datos para cada valor en el rango .. Hey, mira Este sistema permite firmas de más de 60 cha Editado por Arno Brouwer Viernes, Noviembre 23, 2012 4:42 PM Marcado como respuesta por Alexander Sun Viernes, 07 de diciembre de 2012 2:44 Viernes, 23 de noviembre de 2012 16:41 Microsoft está llevando a cabo una encuesta en línea para entender su opinión sobre el sitio web Msdn. Si decide participar, se le presentará la encuesta en línea cuando abandone el sitio Web de Msdn. ¿Quieres participar? Ayúdanos a mejorar MSDN. Visite nuestra página UserVoice para enviar y votar ideas Centros de desarrollo Recursos de aprendizaje Programas de apoyo comunitario

No comments:

Post a Comment