Cómo calcular media móvil ponderada en DAX: paso a paso
Aprende a calcular una media móvil ponderada en DAX para suavizar series temporales y dar más peso a observaciones recientes. Esta técnica es útil para ventas, métricas de usuario o cualquier serie en la que quieras que los eventos más recientes influyan más en el resultado.
Requisitos previos
- Power BI Desktop (u otra herramienta que soporte DAX).
- Una tabla de hechos con columnas: Date (tipo Fecha) y Value (numérico).
- Tabla de fechas relacionada con la tabla de hechos.
Paso 1: Entender la lógica de la media móvil ponderada
Al contrario que la media móvil simple, la media móvil ponderada aplica pesos diferentes a cada punto dentro de la ventana (por ejemplo, últimos 3 o 7 días). Los pesos deben sumar 1 o normalizarse en la fórmula. Se decide la ventana y la secuencia de pesos (ej.: 0.5, 0.3, 0.2 para 3 periodos: más peso en el más reciente).
Paso 2: Crear la medida de suma para el periodo
Primero se crea una medida base que sume los valores. Esto da una referencia limpia para usar dentro de las ventanas.
Total Value = SUM('Facts'[Value])
Paso 3: Medida de media móvil ponderada fija (ej.: 3 periodos)
Para una ventana fija de 3 periodos con pesos [0.5, 0.3, 0.2] — donde el más reciente recibe 0.5 — se usan funciones de contexto temporal. Esta medida asume que la tabla de fechas está relacionada y la selección actual de Date es el punto final de la ventana.
MMW 3 períodos =
VAR w1 = 0.5 -- peso para la fecha actual
VAR w2 = 0.3 -- peso para 1 periodo atrás
VAR w3 = 0.2 -- peso para 2 periodos atrás
VAR d0 = MAX('Date'[Date])
VAR v0 = CALCULATE([Total Value], 'Date'[Date] = d0)
VAR d1 = CALCULATE( MAX('Date'[Date]), FILTER(ALL('Date'), 'Date'[Date] < d0))
VAR v1 = CALCULATE([Total Value], 'Date'[Date] = d1)
VAR d2 = CALCULATE( MAX('Date'[Date]), FILTER(ALL('Date'), 'Date'[Date] < d1))
VAR v2 = CALCULATE([Total Value], 'Date'[Date] = d2)
VAR numerator = w1 * v0 + w2 * v1 + w3 * v2
VAR denom =
(IF(NOT(ISBLANK(v0)), w1, 0)) +
(IF(NOT(ISBLANK(v1)), w2, 0)) +
(IF(NOT(ISBLANK(v2)), w3, 0))
RETURN
IF(denom = 0, BLANK(), numerator / denom)
Paso 4: Medida genérica para N periodos con pesos decrecientes
Para una solución más flexible, se construye una medida que crea dinámicamente la ventana de N periodos y aplica pesos lineales decrecientes (ej.: N, N-1, ..., 1). Esta técnica es útil cuando no quieres especificar manualmente cada peso.
MMW N períodos (linear) =
VAR N = 7 -- ajusta para 3, 7, 14, etc.
VAR EndDate = MAX('Date'[Date])
VAR WindowDates =
TOPN(
N,
FILTER(ALL('Date'), 'Date'[Date] <= EndDate),
'Date'[Date], DESC
)
VAR TableWithValues =
ADDCOLUMNS(
WindowDates,
"ValueOnDate", CALCULATE([Total Value], 'Date'[Date] = EARLIER('Date'[Date]))
)
VAR Ranked =
ADDCOLUMNS(
TableWithValues,
"Rank", RANKX(WindowDates, 'Date'[Date], , DESC, DENSE)
)
VAR WithWeights =
ADDCOLUMNS(
Ranked,
"Weight", DIVIDE( (N + 1 - [Rank]), SUMX(Ranked, N + 1 - [Rank]) )
)
VAR Numerator = SUMX(WithWeights, [Weight] * [ValueOnDate])
VAR Denominator = SUMX(WithWeights, [Weight])
RETURN
IF(Denominator = 0, BLANK(), Numerator / Denominator)
Paso 5: Errores comunes y cómo evitarlos
Errores frecuentes incluyen: no tener una tabla de fechas completa (faltan días), usar MAX sin contexto correcto, o división por cero cuando hay datos missing. Las medidas anteriores usan ALL('Date') y comprobaciones de denom = 0 para evitar estos problemas. Confirma que la relación entre la tabla de hechos y la tabla de fechas está activa y es única.
Verificar el resultado
Crea un gráfico de líneas con 'Date'[Date] en el eje y la medida MMW en el valor. Compara con la serie original (Total Value) para ver la suavización. Usa filtros (slicers) de intervalo de fechas y verifica extremos (inicio de la serie) para confirmar que la medida trata ventanas incompletas correctamente (debe mostrar valores normalizados o BLANK, según la elección).
Conclusión
Ahora tienes dos enfoques para medias móviles ponderadas en DAX: una fija y otra genérica con pesos lineales. Siguientes pasos: experimentar con diferentes esquemas de peso (exponencial), usar la función SAMEPERIODLASTYEAR para comparar y optimizar rendimiento con índices en tablas grandes. Consejo: empieza con N pequeño y valida cada paso con una tabla visual que muestre las fechas, valores y pesos para depuración.