Cómo obtener un valor p en Python
SciPy es la implementación de referencia contra la que se comprueban la mayoría de las demás herramientas, esta incluida. Aquí está cada función que produce un valor p, y la llamada al método que la mantiene exacta en la cola lejana.
8 min de lectura · Última revisión: 7 de agosto de 2026
La respuesta corta
Toda distribución de scipy.stats expone una función de supervivencia,
sf, que es el área de la cola superior. Ese es el valor p de un contraste de
cola derecha.
from scipy import stats
stats.norm.sf(2.5) # z, unilateral
#> 0.006209665325776134
stats.t.sf(2.31, 27) # t, unilateral
#> 0.014384284149660044
2 * stats.t.sf(abs(2.31), 27) # t, bilateral
#> 0.028768568299320087
stats.chi2.sf(7.815, 3) # chi-cuadrado, cola derecha
#> 0.04999390297488388
stats.f.sf(4.26, 2, 27) # F, cola derecha
#> 0.02466186381480589
Chi-cuadrado y F siguen siendo de cola derecha. Duplicarlas no produce un contraste bilateral, produce un número sin significado.
Usa sf, nunca 1 - cdf
Estas dos líneas parecen intercambiables y no lo son:
stats.norm.sf(9)
#> 1.1285884059538324e-19
1 - stats.norm.cdf(9)
#> 0.0
cdf(9) está tan cerca de 1 que la doble precisión lo almacena como 1.
La resta produce entonces exactamente cero, y un resultado que debería ser
1.13 × 10⁻¹⁹ se informa como imposible. sf calcula la cola sin
formar nunca esa diferencia.
Esta es la fuente más habitual de valores p erróneos en el código de análisis, y es la razón de que este sitio escriba a mano su motor de distribuciones en lugar de restar de uno. La página de metodología publica las comparaciones contra estos mismos valores de SciPy.
Contrastes sobre datos en bruto
Si tienes observaciones en lugar de un estadístico, las funciones de contraste devuelven ambas cosas:
from scipy import stats
# Prueba t de Welch: hay que pedirla explícitamente
stats.ttest_ind(a, b, equal_var=False)
# Prueba t de Student (la opción predeterminada de SciPy)
stats.ttest_ind(a, b)
# Emparejada
stats.ttest_rel(before, after)
# Una muestra frente a un valor objetivo
stats.ttest_1samp(x, popmean=100)
# Chi-cuadrado sobre una tabla de contingencia
stats.chi2_contingency([[31, 19], [22, 28]])
# Correlación de Pearson
stats.pearsonr(x, y)
# ANOVA de un factor
stats.f_oneway(group1, group2, group3)
Fíjate en el valor predeterminado que pilla a la gente: ttest_ind supone
varianzas iguales salvo que pases equal_var=False. R hace lo
contrario. Si un resultado de SciPy no coincide con uno de R sobre los mismos datos, esta
suele ser la razón. Welch es la opción más segura y es la que ejecuta esta calculadora.
chi2_contingency también aplica la corrección de continuidad de Yates a las
tablas de 2 × 2 de forma predeterminada. Pasa correction=False para que coincida
con una calculadora sin corrección.
Cómo leer los objetos de resultado
Las versiones modernas de SciPy devuelven tuplas con nombre, así que puedes extraer los campos por nombre en lugar de por posición:
res = stats.ttest_ind(a, b, equal_var=False)
res.pvalue
res.statistic
res.df
# Intervalo de confianza sobre la diferencia
res.confidence_interval(confidence_level=0.95)
La mayoría de las funciones de contraste aceptan además un argumento
alternative —'two-sided', 'less' o
'greater'—, que es más limpio que dividir a mano un valor p bilateral y acierta
la dirección por ti.
Cuando SciPy no basta
SciPy cubre los contrastes de hipótesis estándar. Para una salida de regresión con la tabla
completa de coeficientes, usa statsmodels, que informa un valor p por
coeficiente:
import statsmodels.api as sm
model = sm.OLS(y, sm.add_constant(X)).fit()
model.pvalues
model.summary()
Cómo darle formato para un artículo
Un float en bruto no es un valor p informable. El estilo APA suprime el cero a la izquierda y
corta en tres decimales, así que 0.028768568 se convierte en
p = .029 y cualquier valor por debajo de .001 se informa como
p < .001 y no como p = .000, que nunca es cierto.
def apa(p):
return "p < .001" if p < 0.001 else f"p = {p:.3f}".replace("0.", ".")
La guía de informe en estilo APA cubre el resto, y todas las calculadoras de aquí generan una cadena APA lista para usar junto al resultado.