Based on the current docs, it does not appear that the equivalent of a one-sample t-test is achievable with the permutation_test
function. But it's possible to implement it using numpy
, as shown below. This is based on the R implementation (found here) and this thread on Cross Validated, with options to do a one-sided test and a test against a specific mean added.
import numpy as np
def permutation_ttest_1samp(
data, popmean, n_resamples, alternative='two-sided', random_state=None
):
assert alternative in ('two-sided', 'less', 'greater'), (
"Unrecognized alternative hypothesis"
)
n = len(data)
data = np.asarray(data) - popmean
dbar = np.mean(data)
absx = np.abs(data)
z = []
rng = np.random.RandomState(random_state)
for _ in range(n_resamples):
mn = rng.choice((-1,1), n, replace=True)
xbardash = np.mean(mn * absx)
z.append(xbardash)
z = np.array(z)
if alternative == 'greater':
return 1 - (np.sum(z <= -np.abs(dbar)) / n_resamples)
elif alternative == 'less':
return np.sum(z <= -np.abs(dbar)) / n_resamples
return (
(np.sum(z >= np.abs(dbar)) + np.sum(z <= -np.abs(dbar))) / n_resamples
)
Example 1 (two-sided test against null hypothesis of mean 0):
rng = np.random.RandomState(42)
rvs = rng.normal(loc=0, scale=0.01, size=1000)
pval = permutation_ttest_1samp(rvs, 0, 100_000, alternative='two-sided', random_state=42)
print(pval)
# 0.53206
Comparing to parameterized t-test:
from scipy.stats import ttest_1samp
stat, pval = ttest_1samp(rvs, popmean=0, alternative='two-sided')
print(pval)
# 0.5325672436623021
Example 2 (one-sided test against a non-0 mean null hypothesis)
rng = np.random.RandomState(42)
rvs = rng.normal(loc=0, scale=3, size=1000)
pval = permutation_ttest_1samp(rvs, 0.1, 100_000, alternative='greater', random_state=42)
print(pval)
# 0.6731
Comparing to parameterized t-test:
from scipy.stats import ttest_1samp
stat, pval = ttest_1samp(rvs, popmean=0.1, alternative='greater')
print(pval)
# 0.6743729530216749