Використовуйте .corr, щоб отримати кореляцію між двома стовпцями


127

У мене є такий фрейм даних Top15: введіть тут опис зображення

Я створюю стовпець, в якому оцінюється кількість посилаються документів на людину:

Top15['PopEst'] = Top15['Energy Supply'] / Top15['Energy Supply per Capita']
Top15['Citable docs per Capita'] = Top15['Citable documents'] / Top15['PopEst']

Я хочу знати співвідношення між кількістю цінних документів на душу населення та енергопостачанням на душу населення. Тому я використовую .corr()метод (кореляція Пірсона):

data = Top15[['Citable docs per Capita','Energy Supply per Capita']]
correlation = data.corr(method='pearson')

Я хочу повернути єдине число, але результат такий: введіть тут опис зображення


Я думаю, ти маєш рацію. Але ви можете сказати мені, чому "data.corr (method = 'pearson") "повертає лише взаємозв'язок між енергопостачанням та енергопостачанням?
tong zhu

1
Це не. Він повинен повернути вам матрицю 2x2; ви показуєте його верхній лівий запис. Якщо ви застосуєте .corrбезпосередньо до свого фрейму даних, він поверне всі парні кореляції; тому ви спостерігаєте 1s по діагоналі вашої матриці (кожен стовпчик ідеально співвідноситься з самим собою). Дивіться мою редакцію нижче.
Клеб

1
Будь ласка, подумайте про прийняття відповіді, якщо ви вважаєте, що вона відповіла на ваше запитання
MaxU

1
Я прийняв вашу відповідь, дякую
tong zhu

28
Це питання прямо з курсу «Вступ до науки даних в Python» на Coursera. Зокрема, завдання 3, питання 9. Коли інструктор Кріс Брукс заохочує учнів ставити запитання до Stack Overflow, я не думаю, що він мав на увазі, що вони повинні надсилати проблеми із завданнями дослівно.
LS

Відповіді:


209

Без фактичних даних важко відповісти на питання, але я думаю, ви шукаєте щось подібне:

Top15['Citable docs per Capita'].corr(Top15['Energy Supply per Capita'])

Це обчислює співвідношення між вашими двома стовпцями 'Citable docs per Capita' та 'Energy Supply per Capita'.

Навести приклад:

import pandas as pd

df = pd.DataFrame({'A': range(4), 'B': [2*i for i in range(4)]})

   A  B
0  0  0
1  1  2
2  2  4
3  3  6

Тоді

df['A'].corr(df['B'])

дає 1як очікувалося.

Тепер, якщо ви зміните значення, наприклад

df.loc[2, 'B'] = 4.5

   A    B
0  0  0.0
1  1  2.0
2  2  4.5
3  3  6.0

команда

df['A'].corr(df['B'])

повертає

0.99586

що все ще близько 1, як очікувалося.

Якщо ви застосуєте .corrбезпосередньо до свого фрейму даних, він поверне всі парні кореляції між вашими стовпцями ; ось чому ви потім спостерігаєте 1sпо діагоналі своєї матриці (кожен стовпчик ідеально співвідноситься з самим собою).

df.corr()

тому повернеться

          A         B
A  1.000000  0.995862
B  0.995862  1.000000

На графіці, яку ви показуєте, представлений лише верхній лівий кут кореляційної матриці (я припускаю).

Можуть бути випадки, коли ви отримуєте NaNрішення у своєму рішенні - ознайомтеся з прикладом цього повідомлення .

Якщо ви хочете відфільтрувати записи вище / нижче певного порогу, ви можете перевірити це запитання . Якщо ви хочете побудувати теплову карту коефіцієнтів кореляції, ви можете перевірити цю відповідь, і якщо ви зіткнетеся з проблемою із перекриттями міток осі, перевірте наступний пост .


чи можна це застосовувати за рядком?
Dr.DOOM

1
@ Dr.DOOM: Так, це просто серія, тому, наприклад, df.loc[1, :].corr(df.loc[2, :])буде добре працювати. Для всього dataframe, ви можете просто перенести: df.T.corr().
Клеб

Я спробував вашу пропозицію, проте обчислення все одно повертає 1 навіть після зміни значення у стовпці B, використовуючи df.loc [2, 'B'] = 4.5. можливо, я просто заплутався в обчисленні
Dr.DOOM

@ Dr.DOOM: Важко допомогти, оскільки я не знаю вашого коду. Чи правильно я зрозумів, що мій приклад зверху повертається 1у вашому випадку замість 0.99586?
Клеб

1
@Cleb: Ну, в контексті, в якому я працюю, кожен індекс високих стовпців вищого рівня має однакові підшари. Дивіться це запитання щодо того, що я намагаюся зробити: stackoverflow.com/questions/57513002/…
Адріан

7

Я зіткнувся з тим же питанням. З'явилося, Citable Documents per Personце поплавок, і пітон пропускає його якось за замовчуванням. Усі інші стовпці мого фрейму даних були у numpy-форматах, тому я вирішив це, перетворивши Columnt вnp.float64

Top15['Citable Documents per Person']=np.float64(Top15['Citable Documents per Person'])

Пам'ятайте, що це саме той стовпець, який ви самі обчислили


6

Моє рішення було б після перетворення даних у числовий тип:

Top15[['Citable docs per Capita','Energy Supply per Capita']].corr()

вибір стовпців, а потім застосування методу .corr () - хороший варіант, оскільки ми можемо обчислити кореляцію попарно між більш ніж 2 стовпцями
Sébastien

4

Якщо ви хочете співвідносити між усіма парами стовпців, ви можете зробити щось подібне:

import pandas as pd
import numpy as np

def get_corrs(df):
    col_correlations = df.corr()
    col_correlations.loc[:, :] = np.tril(col_correlations, k=-1)
    cor_pairs = col_correlations.stack()
    return cor_pairs.to_dict()

my_corrs = get_corrs(df)
# and the following line to retrieve the single correlation
print(my_corrs[('Citable docs per Capita','Energy Supply per Capita')])

3

Коли ви телефонуєте цьому:

data = Top15[['Citable docs per Capita','Energy Supply per Capita']]
correlation = data.corr(method='pearson')

Оскільки функція DataFrame.corr () виконує парні кореляції, у вас є чотири пари з двох змінних. Отже, в основному ви отримуєте діагональні значення як автоматичну кореляцію (кореляція з самим собою, два значення, оскільки у вас є дві змінні), а інші два значення як перехресні кореляції одного проти іншого та навпаки.

Виконайте кореляцію між двома серіями, щоб отримати єдине значення:

from scipy.stats.stats import pearsonr
docs_col = Top15['Citable docs per Capita'].values
energy_col = Top15['Energy Supply per Capita'].values
corr , _ = pearsonr(docs_col, energy_col)

або, якщо ви хочете отримати одне значення з тієї ж функції (corr DataFrame):

single_value = correlation[0][1] 

Сподіваюся, це допомагає.


3

Це працює так:

Top15['Citable docs per Capita']=np.float64(Top15['Citable docs per Capita'])

Top15['Energy Supply per Capita']=np.float64(Top15['Energy Supply per Capita'])

Top15['Energy Supply per Capita'].corr(Top15['Citable docs per Capita'])

1

Я вирішив цю проблему, змінивши тип даних. Якщо ви бачите, що "Подача енергії на душу населення" є числовим типом, тоді як "Придатні документи на душу населення" - це тип об'єкта. Я перетворив стовпчик у плаваючий за допомогою astype. У мене була така ж проблема з деякими функціями ір: count_nonzeroі sumпрацював в той час meanі stdне зробив.


0

зміна "Придатних документів на душу населення" на числові до кореляції вирішить проблему.

    Top15['Citable docs per Capita'] = pd.to_numeric(Top15['Citable docs per Capita'])
    data = Top15[['Citable docs per Capita','Energy Supply per Capita']]
    correlation = data.corr(method='pearson')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.