Scipy for loop Ttest 来自字典



我有以下数据帧mmLog:

Experiment       Logmm
0               Spontaneous1       0.022815
1                     Light1       0.007222
2                       PTZ1       0.03168
3               Spontaneous1       0.015003
4                     Light1       0.013402
5                       PTZ1       0.021539
...                      ...            ...
38072  SpontaneousControl147       0.013685
38073  SpontaneousControl147       0.034702
38074  SpontaneousControl147       0.008993

我想从每个唯一组运行一个测试,并将其与"实验"列中的对照组进行比较。我试图创建一个唯一标识符数据帧的字典

df_uniq = dict()
for k, v in mmLog.groupby('Experiment'):
df_uniq[k] = v

,然后使用 for 循环

from scipy.stats import ttest_ind
for key in df_uniq: 
cat1 = key
cat2 = df[df['Experiment']=='SpontaneousControl147']
ttest_ind(cat1['Logmm'], cat2['Logmm'])

并获取类型错误:字符串索引必须是整数

您希望将字典中的值(而不是其键(分配给cat1

from scipy.stats import ttest_ind
results = {}
for key, val in df_uniq.items(): 
cat1 = val
cat2 = df[df['Experiment']=='SpontaneousControl147']
results[key] = ttest_ind(cat1['Logmm'], cat2['Logmm'])

通过将键分配给cat1,您正在尝试对字符串而不是 groupby 结果执行 T 检验。

编辑:您还可以将分配cat2的行拉出循环,因为这只需要完成一次:)

你似乎使这比它需要的更复杂。pd.Dataframe.groupby返回一个pd.GroupBy对象,该对象具有所需的所有属性以及更多属性。无需创建冗余的自定义词典。

例如,从

groups = mmLog.groupby('Experiment')

现在groups.get_group('SpontaneousControl147')将拥有控制组的所有元素:

>>> control = groups.get_group('SpontaneousControl147')['Logmm']
>>> control
38072    0.013685
38073    0.034702
38074    0.008993
Name: Logmm, dtype: float64

或者,您可以使用groups['logmm']只关注您关心的列,这将返回一个SeriesGroupBy对象,您可以从中获取控件数据:

control = groups['Logmm'].get_group('SpontaneousControl147')

在这两种情况下,groups都支持直接迭代以及apply方法。如果您不需要聚合结果:

for key, subset in groups:
if key == 'SpontaneousControl147':
continue
ttest(control, subset['Logmm'])

如果要构建测试值的Series

groups['Logmm'].apply(lambda data: ttest(control, data))

groups.apply(lambda df: ttest(control, df['Logmm']))

这是两个TL;灾难恢复版本:

  1. 使用完整DataFrameGroupBy

    groups = mmLog.groupby('Experiment')
    control = groups.get_group('SpontaneousControl147')['Logmm']
    result = groups.apply(lambda df: ttest(control, df['Logmm']))
    
  2. 使用感兴趣列的SeriesGroupBy

    groups = mmLog.groupby('Experiment')['Logmm']
    control = groups.get_group('SpontaneousControl147')
    result = groups.apply(lamda s: ttest(control, s))
    

最新更新