2016-10-17 4 views
1

Так что я сейчас пытаюсь вычислить R и p-значение Pearson для некоторых данных, которые у меня есть. Это делается с помощью этого кода:Показывать только значение n * n матрицы, если значение из другого n * n имеет определенное значение (Python)

import numpy as np 
from scipy.stats import pearsonr, betai 
from pandas import DataFrame 
import seaborn as sns 
import matplotlib.pyplot as plt 

def corrcoef(matrix): #function that calculates the Pearson's R and p-value 
    r = np.corrcoef(matrix) 
    rf = r[np.triu_indices(r.shape[0], 1)] 
    df = matrix.shape[1] - 2 
    ts = rf * rf * (df/(1 - rf * rf)) 
    pf = betai(0.5 * df, 0.5, df/(df + ts)) 
    p = np.zeros(shape=r.shape) 
    p[np.triu_indices(p.shape[0], 1)] = pf 
    p[np.tril_indices(p.shape[0], -1)] = pf 
    p[np.diag_indices(p.shape[0])] = np.ones(p.shape[0]) 
    return r, p 

data = np.loadtxt('corr-data.txt') #data matrix loaded 

sig_lvl = 0.05 #significance level 

r_mat, p_mat = corrcoef(data) #use function on data and put the answers in two different matrices 

df_rmat = DataFrame(r_mat, columns=Index, index=Index) #make data readable for the seaborn package 
df_pmat = DataFrame(p_mat, columns=Index, index=Index) 

r_mat[abs(r_mat) <= .90] = np.nan #if the R-value matrix elements are under 0.90, don't show them - make them NaN. 
p_mat[abs(p_mat) >= sig_lvl] = np.nan #this is probably the issue. 

mask_pmat = np.zeros_like(p_mat) 
mask_pmat[np.tril_indices_from(mask_pmat)] = True #only showing the upper triangle of the values since it's symmetrical in the diagonal 

sns.plt.subplot(1,2,2) 
ax_pmat = sns.heatmap(np.around(df_pmat, decimals=2), annot=True, mask = mask_pmat) #subplot sequence for the p-value matrix only 

sns.plt.show() 

Это может быть не самый оптимальный код, но на данный момент он работает по назначению. Используя пакет морского ящика, я получаю тепло/цветовой код разных значений, если они достаточно высоки (> = 0,95) или имеют правильный уровень значимости и только верхний треугольник. Однако мне бы хотелось только показать p-значение для тех значений R, которые представлены в первом графике. Значения, которые меньше 0,95, просто заменяются NaN и не являются цветом в тепловой карте. Поэтому только значения в матрице p-значений должны быть представлены, если представлены значения в матрице значений R.

Это можно сделать, или ...?

И, пожалуйста, дайте мне знать, если что-то неясно. Затем я попытаюсь объяснить.

Заранее спасибо

+0

Вы хотите, чтобы логическая переменная с таким же размером, как ваша r-матрица, я думаю. Было бы полезно, если бы вы сделали минимальный рабочий пример более минимальным. – spinup

ответ

2

Я думаю, что вы говорите, это:

p_mat[r_mat < 0.95] = np.nan 

Это работает, потому что p и r имеют такую ​​же форму. Он будет идти в свой код вместо:

if r_mat[abs(r_mat) <= .90] == np.nan: 
    p_mat = np.nan 

Примечание, если сравнить NaN до значения, результат всегда ложно.

+0

Привет, и спасибо за ваш ответ. Я попытался очистить свой код и теперь показывать только нужный материал (надеюсь). Заявление if, которое я сделал, на самом деле не предназначалось для включения, поскольку оно не работало :) Однако ваше предложение, похоже, тоже не работало. В принципе это имеет смысл для меня, но, к сожалению, это не сработало. –

+0

А, так я понял. Я просто изменил две строки r_mat/p_mat: p_mat [abs (p_mat)> = 0,05] = np.nan p_mat [abs (r_mat) <= 0.90] = np.nan r_mat [abs (r_mat) <= 0.90 ] = np.nan , а затем он сработал. Еще раз спасибо за помощь :) –

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