在数据框上按组进行单边单样本 T 检验?
One-sided one sample T test by group on data frame?
我正在尝试在 python 中的 pandas 数据帧上按组执行单侧单样本 T 检验。我觉得我已经很接近了,但我无法关闭最后一点。我试图遵循与这些问题类似的问题 (One Sided One Sample T Test Python and )。
比如说我有一个数据框df
df = pd.DataFrame({'ID': ['A', 'A', 'A', 'A', 'A',
'B', 'B', 'B', 'B', 'B',
'C', 'C', 'C', 'C', 'C'],
'value': [0.200, 0.201, 0.189, 0.199, 0.205,
0.220, 0.225, 0.209, 0.218, 0.230,
0.308, 0.291, 0.340, 0.444, 0.275]})
我想生成一个只有两列的新数据框 df_pval
:'ID' 和单边样本 T 检验的 p 值。我可以在 R 中这样做:
library(dplyr)
df_pval <- df %>%
group_by(ID) %>%
summarise(res = list(t.test(value, mu = 0.220, alternative = 'greater')))
df_pval <- data.frame(ID = df_pval$ID,
pval = sapply(df_pval$res, function(x) x[['p.value']]))
事实上,现在我使用 os
到 运行 外部 R 脚本来执行此操作,但我知道它必须在 python 中才有可能。我尝试创建一个 'groupby' 对象,然后 运行ning .apply
:
df_groupID = df.groupby('ID').agg({'value': list})
df_groupID.apply(lambda x: stats.ttest_1samp(x['value'], 0.220))
但这不起作用。到目前为止,我被困住了。对此问题的任何帮助将不胜感激。预先感谢您,如果之前已经回答过这个问题(我只是不明白解决方案),我们深表歉意。
也许尝试这样的事情(使用 scipy-1.7.3
):
import pandas as pd
from scipy import stats
df = pd.DataFrame({'ID': ['A', 'A', 'A', 'A', 'A',
'B', 'B', 'B', 'B', 'B',
'C', 'C', 'C', 'C', 'C'],
'value': [0.200, 0.201, 0.189, 0.199, 0.205,
0.220, 0.225, 0.209, 0.218, 0.230,
0.308, 0.291, 0.340, 0.444, 0.275]})
df_groupID = df.groupby('ID').agg({'value': list})
df_groupID['value'] = df_groupID.value.apply(lambda x : stats.ttest_1samp(x, 0.220, alternative='greater').pvalue)
df_groupID = df_groupID.rename(index=str, columns={'value':'pval'})
pval
ID
A 0.999335
B 0.457619
C 0.010342
相当于:
library(dplyr)
df <- data.frame(
ID = c ('A', 'A', 'A', 'A', 'A',
'B', 'B', 'B', 'B', 'B',
'C', 'C', 'C', 'C', 'C'),
value = c(0.200, 0.201, 0.189, 0.199, 0.205,
0.220, 0.225, 0.209, 0.218, 0.230,
0.308, 0.291, 0.340, 0.444, 0.275)
)
df_pval <- df %>%
group_by(ID) %>%
summarise(res = list(t.test(value, mu = 0.220, alternative = 'greater')))
df_pval <- data.frame(ID = df_pval$ID,
pval = sapply(df_pval$res, function(x) x[['p.value']]))
print(df_pval)
ID pval
1 A 0.99933491
2 B 0.45761885
3 C 0.01034185
对于 one-sided 测试,这应该适用于任何版本的 scipy:
import pandas as pd
from scipy import stats
df = pd.DataFrame({'ID': ['A', 'A', 'A', 'A', 'A',
'B', 'B', 'B', 'B', 'B',
'C', 'C', 'C', 'C', 'C'],
'value': [0.200, 0.201, 0.189, 0.199, 0.205,
0.220, 0.225, 0.209, 0.218, 0.230,
0.308, 0.291, 0.340, 0.444, 0.275]})
df.groupby('ID')['value'].apply(lambda x: stats.ttest_1samp(list(x),
popmean=0.220).pvalue/2) # divide by 2 for one-sided (alternative='greater' or 'smaller')
给出:
ID
A 0.000665
B 0.457619
C 0.010342
我正在尝试在 python 中的 pandas 数据帧上按组执行单侧单样本 T 检验。我觉得我已经很接近了,但我无法关闭最后一点。我试图遵循与这些问题类似的问题 (One Sided One Sample T Test Python and
比如说我有一个数据框df
df = pd.DataFrame({'ID': ['A', 'A', 'A', 'A', 'A',
'B', 'B', 'B', 'B', 'B',
'C', 'C', 'C', 'C', 'C'],
'value': [0.200, 0.201, 0.189, 0.199, 0.205,
0.220, 0.225, 0.209, 0.218, 0.230,
0.308, 0.291, 0.340, 0.444, 0.275]})
我想生成一个只有两列的新数据框 df_pval
:'ID' 和单边样本 T 检验的 p 值。我可以在 R 中这样做:
library(dplyr)
df_pval <- df %>%
group_by(ID) %>%
summarise(res = list(t.test(value, mu = 0.220, alternative = 'greater')))
df_pval <- data.frame(ID = df_pval$ID,
pval = sapply(df_pval$res, function(x) x[['p.value']]))
事实上,现在我使用 os
到 运行 外部 R 脚本来执行此操作,但我知道它必须在 python 中才有可能。我尝试创建一个 'groupby' 对象,然后 运行ning .apply
:
df_groupID = df.groupby('ID').agg({'value': list})
df_groupID.apply(lambda x: stats.ttest_1samp(x['value'], 0.220))
但这不起作用。到目前为止,我被困住了。对此问题的任何帮助将不胜感激。预先感谢您,如果之前已经回答过这个问题(我只是不明白解决方案),我们深表歉意。
也许尝试这样的事情(使用 scipy-1.7.3
):
import pandas as pd
from scipy import stats
df = pd.DataFrame({'ID': ['A', 'A', 'A', 'A', 'A',
'B', 'B', 'B', 'B', 'B',
'C', 'C', 'C', 'C', 'C'],
'value': [0.200, 0.201, 0.189, 0.199, 0.205,
0.220, 0.225, 0.209, 0.218, 0.230,
0.308, 0.291, 0.340, 0.444, 0.275]})
df_groupID = df.groupby('ID').agg({'value': list})
df_groupID['value'] = df_groupID.value.apply(lambda x : stats.ttest_1samp(x, 0.220, alternative='greater').pvalue)
df_groupID = df_groupID.rename(index=str, columns={'value':'pval'})
pval
ID
A 0.999335
B 0.457619
C 0.010342
相当于:
library(dplyr)
df <- data.frame(
ID = c ('A', 'A', 'A', 'A', 'A',
'B', 'B', 'B', 'B', 'B',
'C', 'C', 'C', 'C', 'C'),
value = c(0.200, 0.201, 0.189, 0.199, 0.205,
0.220, 0.225, 0.209, 0.218, 0.230,
0.308, 0.291, 0.340, 0.444, 0.275)
)
df_pval <- df %>%
group_by(ID) %>%
summarise(res = list(t.test(value, mu = 0.220, alternative = 'greater')))
df_pval <- data.frame(ID = df_pval$ID,
pval = sapply(df_pval$res, function(x) x[['p.value']]))
print(df_pval)
ID pval
1 A 0.99933491
2 B 0.45761885
3 C 0.01034185
对于 one-sided 测试,这应该适用于任何版本的 scipy:
import pandas as pd
from scipy import stats
df = pd.DataFrame({'ID': ['A', 'A', 'A', 'A', 'A',
'B', 'B', 'B', 'B', 'B',
'C', 'C', 'C', 'C', 'C'],
'value': [0.200, 0.201, 0.189, 0.199, 0.205,
0.220, 0.225, 0.209, 0.218, 0.230,
0.308, 0.291, 0.340, 0.444, 0.275]})
df.groupby('ID')['value'].apply(lambda x: stats.ttest_1samp(list(x),
popmean=0.220).pvalue/2) # divide by 2 for one-sided (alternative='greater' or 'smaller')
给出:
ID
A 0.000665
B 0.457619
C 0.010342