在不使用数组的情况下进行scipy.stats.ttest_ind(python)

3 投票
3 回答
3371 浏览
提问于 2025-04-18 14:24

我做了一些计算,想要估算出两个样本的平均值(μ)、标准差(σ)和样本数量(N)。因为我做了一些简化,所以我没有准备好scipy.stats.ttest_ind所需要的数组。如果我没记错的话,我只需要μ、σ和N就可以进行Welch的t检验。请问在Python中有没有办法做到这一点?

3 个回答

1

我写了t检验和z检验的函数,这些函数可以处理statsmodels的汇总统计数据。

这些函数主要是为了内部使用,方便避免重复写代码,所以文档说明得不太详细。

比如,你可以查看这个链接:http://statsmodels.sourceforge.net/devel/generated/statsmodels.stats.weightstats._tstat_generic.html

相关函数的列表在这里:http://statsmodels.sourceforge.net/devel/stats.html#basic-statistics-and-t-tests-with-frequency-weights

编辑:回复评论

这个函数只是做了核心计算,关于在不同假设下计算差异的标准差的具体实现,是在调用这个函数的方法中添加的。你可以查看这个链接了解更多:https://github.com/statsmodels/statsmodels/blob/master/statsmodels/stats/weightstats.py#L713

编辑

这里有一个例子,展示如何使用CompareMeans类的方法,这个类的t检验是基于汇总统计的。我们需要创建一个类,把相关的汇总统计作为属性保存。最后有一个函数,简单地封装了相关的调用。

"""
Created on Wed Jul 23 05:47:34 2014
Author: Josef Perktold
License: BSD-3

"""

import numpy as np
from scipy import stats
from statsmodels.stats.weightstats import CompareMeans, ttest_ind


class SummaryStats(object):

    def __init__(self, nobs, mean, std):
        self.nobs = nobs
        self.mean = mean
        self.std = std
        self._var = std**2

np.random.seed(123)
nobs = 20
x1 = 1 + np.random.randn(nobs)
x2 = 1 + 1.5 * np.random.randn(nobs)

print stats.ttest_ind(x1, x2, equal_var=False)
print ttest_ind(x1, x2, usevar='unequal')

s1 = SummaryStats(x1.shape[0], x1.mean(0), x1.std(0))
s2 = SummaryStats(x2.shape[0], x2.mean(0), x2.std(0))

print CompareMeans(s1, s2).ttest_ind(usevar='unequal')



def ttest_ind_summ(summ1, summ2, usevar='unequal'):
    """t-test for equality of means based on summary statistic

    Parameters
    ----------
    summ1, summ2 : tuples of (nobs, mean, std)
        summary statistic for the two samples

    """

    s1 = SummaryStats(*summ1)
    s2 = SummaryStats(*summ2)
    return CompareMeans(s1, s2).ttest_ind(usevar=usevar)

print ttest_ind_summ((x1.shape[0], x1.mean(0), x1.std(0)),
                     (x2.shape[0], x2.mean(0), x2.std(0)), 
                     usevar='unequal')

''' result
(array(1.1590347327654558), 0.25416326823881513)
(1.1590347327654555, 0.25416326823881513, 35.573591346616553)
(1.1590347327654558, 0.25416326823881513, 35.57359134661656)
(1.1590347327654558, 0.25416326823881513, 35.57359134661656)
'''
3

这里有一个简单的实现,基于这个链接

import scipy.stats as stats
import numpy as np

def welch_t_test(mu1, s1, N1, mu2, s2, N2):
  # Construct arrays to make calculations more succint.
  N_i = np.array([N1, N2])
  dof_i = N_i - 1
  v_i = np.array([s1, s2]) ** 2
  # Calculate t-stat, degrees of freedom, use scipy to find p-value.
  t = (mu1 - mu2) / np.sqrt(np.sum(v_i / N_i))
  dof = (np.sum(v_i / N_i) ** 2) / np.sum((v_i ** 2) / ((N_i ** 2) * dof_i))
  p = stats.distributions.t.sf(np.abs(t), dof) * 2
  return t, p

它的结果几乎是完全一样的:

sample1 = np.random.rand(10)
sample2 = np.random.rand(15)
result_test = welch_t_test(np.mean(sample1), np.std(sample1, ddof=1), sample1.size,
                           np.mean(sample2), np.std(sample2, ddof=1), sample2.size)
result_scipy = stats.ttest_ind(sample1, sample2,equal_var=False)
np.allclose(result_test, result_scipy)
True
2

更新说明

这个功能现在在 scipy.stats 中可以使用了,从版本 0.16.0 开始就有了。

你可以在这里查看相关文档

scipy.stats.ttest_ind_from_stats(mean1, std1, nobs1, mean2, std2, nobs2, equal_var=True)
T-test for means of two independent samples from descriptive statistics.

This is a two-sided test for the null hypothesis that 2 independent samples have identical average (expected) values.

撰写回答