MOOD
Overview
The MOOD
function performs Mood’s two-sample test for scale parameters, a non-parametric test used to determine if two independent samples differ in their scale (variance). Unlike parametric tests such as the F-test, Mood’s test does not require the assumption of normality and is robust to outliers. The test statistic is based on the ranks of the combined samples:
where and are the two samples, and is the indicator function. For more details, see the scipy.stats.mood documentation .
This Excel wrapper simplifies the function by only exposing the most commonly used parameters: the two sample arrays and the alternative hypothesis. Parameters such as axis
, nan_policy
, and keepdims
are omitted for Excel compatibility. This example function is provided as-is without any representation of accuracy.
Usage
To use the function in Excel:
=MOOD(x, y, [alternative])
x
(2D list, required): First sample group. Must be a 2D array (table) with at least two rows.y
(2D list, required): Second sample group. Must be a 2D array (table) with at least two rows.alternative
(string, optional, default="two-sided"
): Defines the alternative hypothesis. Must be one of"two-sided"
,"less"
, or"greater"
.
The function returns a 2D array with two float values: [[statistic, pvalue]]
, or an error message (string) if the input is invalid. The statistic measures the difference in scale between the two samples, and the p-value indicates the significance of the result.
Examples
Example 1: Basic Two-Sided Test
Inputs:
x | y | alternative | ||
---|---|---|---|---|
1.2 | 2.3 | 2.1 | 3.2 | two-sided |
3.4 | 4.5 | 4.3 | 5.4 |
Excel formula:
=MOOD({1.2,2.3;3.4,4.5}, {2.1,3.2;4.3,5.4})
Expected output:
Statistic | P-value |
---|---|
0.000 | 1.000 |
Example 2: “Less” Alternative
Inputs:
x | y | alternative | ||
---|---|---|---|---|
1.2 | 2.3 | 2.1 | 3.2 | less |
3.4 | 4.5 | 4.3 | 5.4 |
Excel formula:
=MOOD({1.2,2.3;3.4,4.5}, {2.1,3.2;4.3,5.4}, "less")
Expected output:
Statistic | P-value |
---|---|
0.000 | 0.500 |
Example 3: “Greater” Alternative
Inputs:
x | y | alternative | ||
---|---|---|---|---|
1.2 | 2.3 | 2.1 | 3.2 | greater |
3.4 | 4.5 | 4.3 | 5.4 |
Excel formula:
=MOOD({1.2,2.3;3.4,4.5}, {2.1,3.2;4.3,5.4}, "greater")
Expected output:
Statistic | P-value |
---|---|
0.000 | 0.500 |
Example 4: Different Samples
Inputs:
x | y | alternative | ||
---|---|---|---|---|
10.0 | 12.0 | 1.0 | 2.0 | two-sided |
14.0 | 16.0 | 3.0 | 4.0 |
Excel formula:
=MOOD({10.0,12.0;14.0,16.0}, {1.0,2.0;3.0,4.0})
Expected output:
Statistic | P-value |
---|---|
0.000 | 1.000 |
Python Code
from scipy.stats import mood as scipy_mood
from typing import List, Union
def mood(x: List[List[float]], y: List[List[float]], alternative: str = 'two-sided') -> Union[List[List[float]], str]:
"""
Performs Mood's two-sample test for scale parameters (non-parametric).
Args:
x: 2D list of float values. First sample group.
y: 2D list of float values. Second sample group.
alternative: Defines the alternative hypothesis ('two-sided', 'less', 'greater'). Default is 'two-sided'.
Returns:
2D list with two float values: [[statistic, pvalue]], or an error message (str) if input is invalid.
This example function is provided as-is without any representation of accuracy.
"""
# Validate x and y are 2D lists with at least two rows
if not (isinstance(x, list) and all(isinstance(row, list) for row in x) and len(x) >= 2):
return "Invalid input: x must be a 2D list with at least two rows."
if not (isinstance(y, list) and all(isinstance(row, list) for row in y) and len(y) >= 2):
return "Invalid input: y must be a 2D list with at least two rows."
# Flatten x and y
try:
x_flat = [float(item) for row in x for item in row]
y_flat = [float(item) for row in y for item in row]
except Exception:
return "Invalid input: x and y must contain only numeric values."
if len(x_flat) < 2 or len(y_flat) < 2:
return "Invalid input: each sample must contain at least two values."
# Validate alternative
if alternative not in ['two-sided', 'less', 'greater']:
return "Invalid input: alternative must be 'two-sided', 'less', or 'greater'."
# Call scipy.stats.mood
try:
stat, pvalue = scipy_mood(x_flat, y_flat, alternative=alternative)
except Exception as e:
return f"scipy.stats.mood error: {e}"
# Convert numpy types to Python float
try:
stat = float(stat)
pvalue = float(pvalue)
except Exception:
return "Invalid result: could not convert output to float."
# Check for nan/inf
if any([isinstance(val, float) and (val != val or val in [float('inf'), float('-inf')]) for val in [stat, pvalue]]):
return "Invalid result: statistic or pvalue is nan or inf."
return [[stat, pvalue]]