корреляция столбцов pandas со статистической значимостью

Каков наилучший способ, с учетом pandas dataframe, df, получить корреляцию между его столбцами df.1 и df.2?

Я хочу, чтобы результат не подсчитывал строки с NaN, которые делают pandas в корреляции. Но я также хочу, чтобы он выдавал значение pvalue или стандартную ошибку, которую не использует встроенный.

Sci py, похоже, догнал NaNs, хотя я считаю, что он сообщает о значимости …

Пример данных:

1 2 0 2 NaN 1 NaN 1 2 1 2 3 -4 3 4 1.3 1 5 NaN NaN 

  • Пиксельные соседи в массиве 2d (изображение) с использованием Python
  • подгонка многовариантных curve_fit в python
  • Интерполяция Python / Scipy 2D (неравномерные данные)
  • Линейная интерполяция Python 4D на прямоугольной сетке
  • Как читать часть двоичного файла с numpy?
  • Инструмент для преобразования кода MATLAB в Python
  • Сгладить список вложенных списков с переменными размерами в массив SciPy
  • Формула Планков для спектра Blackbody
  • 4 Solutions collect form web for “корреляция столбцов pandas со статистической значимостью”

    Метод Шашанка хорош. Однако, если вам нужно решение в чистых пандах, вам может понравиться следующее:

     import pandas as pd from pandas.io.data import DataReader from datetime import datetime import scipy.stats as stats gdp = pd.DataFrame(DataReader("GDP", "fred", start=datetime(1990, 1, 1))) vix = pd.DataFrame(DataReader("VIXCLS", "fred", start=datetime(1990, 1, 1))) #Do it with a pandas regression to get the p value from the F-test df = gdp.merge(vix,left_index=True, right_index=True, how='left') vix_on_gdp = pd.ols(y=df['VIXCLS'], x=df['GDP'], intercept=True) print(df['VIXCLS'].corr(df['GDP']), vix_on_gdp.f_stat['p-value']) 

    Результаты:

     -0.0422917932738 0.851762475093 

    Те же результаты, что и функция статистики:

     #Do it with stats functions. df_clean = df.dropna() stats.pearsonr(df_clean['VIXCLS'], df_clean['GDP']) 

    Результаты:

      (-0.042291793273791969, 0.85176247509284908) 

    Чтобы расширить доступ к большим количествам, я даю вам уродливый подход на основе петли:

     #Add a third field oil = pd.DataFrame(DataReader("DCOILWTICO", "fred", start=datetime(1990, 1, 1))) df = df.merge(oil,left_index=True, right_index=True, how='left') #construct two arrays, one of the correlation and the other of the p-vals rho = df.corr() pval = np.zeros([df.shape[1],df.shape[1]]) for i in range(df.shape[1]): # rows are the number of rows in the matrix. for j in range(df.shape[1]): JonI = pd.ols(y=df.icol(i), x=df.icol(j), intercept=True) pval[i,j] = JonI.f_stat['p-value'] 

    Результаты rho:

      GDP VIXCLS DCOILWTICO GDP 1.000000 -0.042292 0.870251 VIXCLS -0.042292 1.000000 -0.004612 DCOILWTICO 0.870251 -0.004612 1.000000 

    Результаты pval:

      [[ 0.00000000e+00 8.51762475e-01 1.11022302e-16] [ 8.51762475e-01 0.00000000e+00 9.83747425e-01] [ 1.11022302e-16 9.83747425e-01 0.00000000e+00]] 

    Вы можете использовать корреляционные функции scipy.stats для получения значения p.

    Например, если вы ищете корреляцию, такую ​​как корреляция pearson, вы можете использовать функцию pearsonr .

     from scipy.stats import pearsonr pearsonr([1, 2, 3], [4, 3, 7]) 

    Дает выход

     (0.7205766921228921, 0.48775429164459994) 

    Где первое значение в кортеже – это значение корреляции, а второе – p-значение.

    В вашем случае вы можете использовать функцию dropna ' dropna чтобы сначала удалить значения NaN .

     df_clean = df[['column1', 'column2']].dropna() pearsonr(df_clean['column1'], df_clean['column2']) 

    Чтобы вычислить все значения p сразу , вы можете использовать calculate_pvalues функцию calculate_pvalues :

     df = pd.DataFrame({'A':[1,2,3], 'B':[2,5,3], 'C':[5,2,1], 'D':['text',2,3] }) calculate_pvalues(df) 
    • Результат похож на corr() (но с p-значениями):

        ABC A 0 0.7877 0.1789 B 0.7877 0 0.6088 C 0.1789 0.6088 0 
    • p-значения округляются до 4 десятичных знаков

    • Столбец D игнорируется, поскольку он содержит текст.

    Ниже приведен код функции :

     from scipy.stats import pearsonr import pandas as pd def calculate_pvalues(df): df = df.dropna()._get_numeric_data() dfcols = pd.DataFrame(columns=df.columns) pvalues = dfcols.transpose().join(dfcols, how='outer') for r in df.columns: for c in df.columns: pvalues[r][c] = round(pearsonr(df[r], df[c])[1], 4) return pvalues 

    Я попытался суммировать логику в функции, это может быть не самый эффективный подход, но предоставит вам аналогичный результат, как pandas df.corr (). Чтобы использовать это, просто поместите в свой код следующую функцию и вызовите ее, предоставляя свой объект dataframe, т. Е. corr_pvalue (your_dataframe) .

    Я округлял значения до 4 знаков после запятой, в случае, если вам нужен другой выход, пожалуйста, измените значение в круглой функции.

     def corr_pvalue(df): from scipy.stats import pearsonr import numpy as np import pandas as pd numeric_df = df.dropna()._get_numeric_data() cols = numeric_df.columns mat = numeric_df.values arr = np.zeros((len(cols),len(cols)), dtype=object) for xi, x in enumerate(mat.T): for yi, y in enumerate(mat.T[xi:]): arr[xi, yi+xi] = map(lambda _: round(_,4), pearsonr(x,y)) arr[yi+xi, xi] = arr[xi, yi+xi] return pd.DataFrame(arr, index=cols, columns=cols) 

    Я тестировал его с помощью pandas v0.18.1

    Python - лучший язык программирования в мире.