2016-05-09 4 views
2

Цель:Т-тест на одном DataFrame с группами из другого DataFrame

Выполните т-тест на DataFrame (df_rna), используя группу найден в другом DataFrame (df_cnv). Уменьшите тест DataFrame (df_rna) индексов строк с наиболее значимыми оценками из t-теста.

Пример кода:

# Dataframe (df_cnv) that forms groups of columns (cells) either\ belonging to True or False for t-test. 
cnv = {'gene': ['x','y','z','n'], 
     'cell_a': [0,-1,0,-1], 
     'cell_b': [0,-1,-1,-1], 
     'cell_c': [-1,0,-1,0], 
     'cell_d': [-1,0,-1,0], 
     'cell_e': [-1,0,0,0] 
     } 
df_cnv = pd.DataFrame(cnv) 
df_cnv.set_index('gene', inplace=True) 
cnv_mask = df_cnv < 0 
cnv_mask # True values are negative (gene loss is True) 

cnv_mask masked for negative values

# DataFrame for t-test and subsequent reduction to most significant rows 
rna = {'gene': ['x','y','z','n'], 
      'cell_a': [1, 5, 8,9], 
      'cell_b': [8, 5, 4,9], 
      'cell_c': [8, 6, 1,1], 
      'cell_d': [1, 2, 7,1], 
      'cell_e': [5, 7, 9,1], 
      } 
    df_rna = pd.DataFrame(rna) 
    df_rna.set_index('gene') 

df_rna

# Manually computed T-Tests, save results in DataFrame df_report 
x = scipy.stats.ttest_ind([8,1,5],[1,8]) 
y = scipy.stats.ttest_ind([5,5], [6,2,7]) 
z = scipy.stats.ttest_ind([4,1,7], [8,9]) 
n = scipy.stats.ttest_ind([9,9], [1,1,1]) 

tStat = [gene.statistic for gene in [x,y,z,n]] 
pVal = [gene.pvalue for gene in [x,y,z,n]] 

report = {'gene':['x','y','z','n'], 
     't_stat':tStat, 
     'p_val':pVal} 
df_report = pd.DataFrame(report) 
df_report.set_index('gene', inplace=True) 

df_report from t-test

# Create reduced version of test DataFrame (df_rna) to contain only rows (genes 
df_pass = df_report.loc[df_report['p_val'] < 0.05] 
passed_genes = set(df_pass.index) 
passed_genes 

df_rna_pass = df_rna.loc[df_rna['gene'].isin(passed_genes)] 
df_rna_pass.set_index('gene') 

df_rna_pass reduced df_rna DataFrame with only rows with p_val < 0.05

Вопрос:

Ручная настройка Т-тест группы не представляется возможным для моего большого набора данных. Как я могу вычислить все статистические данные t-теста во всем DataFrame df_rna, когда группы ячеек True или False изменяются для каждой строки?

Mystery Ханг: (бывает, если ваш не кэшировать результаты rnadf_all[~cnv_mask])

C:\Users\test\Anaconda3\lib\site-packages\numpy\core\_methods.py:82: RuntimeWarning: Degrees of freedom <= 0 for slice 
    warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning) 
--------------------------------------------------------------------------- 
KeyboardInterrupt       Traceback (most recent call last) 
<ipython-input-16-ccabe33b2612> in <module>() 
    34 
    35 for r in rnadf_all[cnv_mask].iterrows(): 
---> 36  df_report.at[r[0], 't_stat'], df_report.at[r[0], 'p_val'] = scipy.stats.ttest_ind(r[1].dropna(), rnadf_all[~cnv_mask].loc[r[0]].dropna()) 
    37 
    38 df_pass = df_report.loc[df_report['p_val'] < 0.05] 

C:\Users\test\Anaconda3\lib\site-packages\pandas\core\frame.py in __getitem__(self, key) 
    1963    return self._getitem_array(key) 
    1964   elif isinstance(key, DataFrame): 
-> 1965    return self._getitem_frame(key) 
    1966   elif is_mi_columns: 
    1967    return self._getitem_multilevel(key) 

C:\Users\test\Anaconda3\lib\site-packages\pandas\core\frame.py in _getitem_frame(self, key) 
    2036   if key.values.dtype != np.bool_: 
    2037    raise ValueError('Must pass DataFrame with boolean values only') 
-> 2038   return self.where(key) 
    2039 
    2040  def query(self, expr, **kwargs): 

C:\Users\test\Anaconda3\lib\site-packages\pandas\core\generic.py in where(self, cond, other, inplace, axis, level, try_cast, raise_on_error) 
    3931   # try to align 
    3932   try_quick = True 
-> 3933   if hasattr(other, 'align'): 
    3934 
    3935    # align with me 

KeyboardInterrupt: 

ответ

1
from scipy import stats 

# Create empty DF for t-test results 
df_report = pd.DataFrame(index=df_rna.index, columns=['p_val', 't_stat']) 

not_df_rna = df_rna[~cnv_mask] 

# Iterate through df_rna rows, apply mask, drop NaN values, run ttest_ind and save result to df_report 
for r in df_rna[cnv_mask].iterrows(): 
    df_report.at[r[0], 't_stat'], df_report.at[r[0], 'p_val'] = stats.ttest_ind(r[1].dropna(), not_df_rna.loc[r[0]].dropna()) 

Результат:

df_report 

     p_val  t_stat 
gene      
x  0.966863 0.0450988 
y   1   0 
z  0.141358 -1.98508 
n   0  inf 
+0

это решение зависает и выдает предупреждение 'C: \ Users \ test \ Anaconda3 \ lib \ site-packages \ numpy \ core \ _methods.py: 82: RuntimeWarning: Степени свободы <= 0 для фрагментов предупреждений. warn («Степени свободы <= 0 для среза», RuntimeWarning). Я никогда не видел этого раньше. Является ли это проблемой? –

+1

Я не заметил, что вы разместили Traceback. Можете ли вы проверить, сколько времени требуется, чтобы применить ~ cnv_mask к rnadf_all: rnadf_all [~ cnv_mask]? С большим DataFrame мое решение не оптимально, так как это будет сделано на каждой итерации цикла. Так что лучше сделать это один раз перед циклом и кэшировать результат: not_rnadf_all = rnadf_all [~ cnv_mask]; затем в цикле замените rnadf_all [~ cnv_mask] .loc [r [0]]. dropna() с not_rnadf_all.loc [r [0]]. dropna() – wombatonfire

+1

Я представил каждый пример (оптимальный и менее оптимальный) в нашу школу вычислить кластер 15 часов назад. Оптимальный один закончен (с тем, что кажется разумным результатом) в 00:02:01 процессорное время с max vmem на 5.174G. Менее оптимальный, по-видимому, работает ... –

1

Я бы начать с перестановкой двух ДФХ , и создание нового DF для результатов t-теста:

cnv_mask_t = cnv_mask.transpose() 
df_rna_t = df_rna.transpose() 
df_tres = pd.dataframe(index=df_rna.index, columns=['pval', 'stat']) 

Затем вы можете перебрать гены, которые теперь столбцы и фильтровать для значений, в котором маска содержит True:

for gene in df_rna_t: 
    col_mask = cnv_mask_t[gene] 
    tres = scipy.stats.ttest_ind(df_rna_t[gene][col_mask], df_rna_t[gene][~col_mask]) 
    df_tres.loc[gene] = [tres.pvalue, tres.statistic] 

Я предполагаю, что вы можете взять его отсюда.

+1

P.S. Я в настоящее время на мобильных устройствах, поэтому я не могу проверить код. Дайте мне знать, если вам нужна дополнительная помощь, и я обязательно буду изучать ее, когда я попаду на компьютер. – Shovalt

+0

Очень чистый и очень чистый питон. Перенос - единственная проблема, так как я работаю с несколькими кадрами данных размером около 3000 с на 20 000 строк. В противном случае очень легко понять, но какова роль тильды в '[~ col_mask]'? –

+0

Он отменяет булевский вектор, позволяя выбирать все ячейки, в которых маска False. – Shovalt

Смежные вопросы