Gunakan .corr untuk mendapatkan korelasi antara dua kolom

127

Saya memiliki dataframe panda berikut Top15: masukkan deskripsi gambar di sini

Saya membuat kolom yang memperkirakan jumlah dokumen citable per orang:

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

Saya ingin mengetahui korelasi antara jumlah dokumen citable per kapita dan pasokan energi per kapita. Jadi saya menggunakan .corr()metode (korelasi Pearson):

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

Saya ingin mengembalikan satu angka, tetapi hasilnya adalah: masukkan deskripsi gambar di sini

tong zhu
sumber
Saya pikir Anda benar. Tetapi dapatkah Anda memberi tahu saya mengapa 'data.corr (method =' pearson ')' hanya mengembalikan hubungan antara Pasokan Energi dan Suplai Energi?
tong zhu
1
Itu tidak. Ini harus mengembalikan Anda matriks 2x2; Anda menunjukkan entri kiri atasnya. Jika Anda menerapkan .corrlangsung ke kerangka data Anda, itu akan mengembalikan semua korelasi berpasangan; itulah mengapa Anda kemudian mengamati 1 di diagonal matriks Anda (setiap kolom berkorelasi sempurna dengan dirinya sendiri). Lihat hasil edit saya di bawah.
Cleb
1
Harap pertimbangkan untuk menerima jawaban jika menurut Anda jawaban itu telah menjawab pertanyaan Anda
MaxU
1
Saya telah menerima jawaban Anda, terima kasih
tong zhu
29
Pertanyaan ini langsung dari kursus "Pengantar Ilmu Data dengan Python" di Coursera. Secara khusus, tugas 3, pertanyaan 9. Ketika instruktur Chris Brooks mendorong siswa untuk mengirim pertanyaan ke Stack Overflow, menurut saya dia tidak bermaksud bahwa mereka harus memposting masalah dari tugas secara verbatim.
LS

Jawaban:

210

Tanpa data aktual, sulit untuk menjawab pertanyaan tetapi saya rasa Anda mencari sesuatu seperti ini:

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

Itu menghitung korelasi antara dua kolom Anda 'Citable docs per Capita' dan 'Energy Supply per Capita'.

Sebagai contoh:

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

Kemudian

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

berikan 1seperti yang diharapkan.

Sekarang, jika Anda mengubah nilai, mis

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

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

perintah

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

kembali

0.99586

yang masih mendekati 1, seperti yang diharapkan.

Jika Anda menerapkan .corrlangsung ke kerangka data Anda, itu akan mengembalikan semua korelasi berpasangan antara kolom Anda ; itulah mengapa Anda kemudian mengamati 1sdiagonal matriks Anda (setiap kolom berkorelasi sempurna dengan dirinya sendiri).

df.corr()

karena itu akan kembali

          A         B
A  1.000000  0.995862
B  0.995862  1.000000

Dalam grafik yang Anda tunjukkan, hanya sudut kiri atas dari matriks korelasi yang diwakili (saya asumsikan).

Mungkin ada kasus, di mana Anda mendapatkan NaNsolusi Anda - lihat posting ini untuk contoh.

Jika Anda ingin memfilter entri di atas / di bawah ambang tertentu, Anda dapat memeriksa pertanyaan ini . Jika Anda ingin memplot peta panas dari koefisien korelasi, Anda dapat memeriksa jawaban ini dan jika Anda kemudian mengalami masalah dengan label sumbu yang tumpang tindih, periksa posting berikut .

Cleb
sumber
bisakah ini diterapkan per baris?
Dr. DOOM
1
@ Dr. DOOM: Ya, ini hanya membutuhkan seri, jadi misalnya df.loc[1, :].corr(df.loc[2, :])akan bekerja dengan baik juga. Untuk seluruh dataframe, Anda hanya dapat transpos: df.T.corr().
Cleb
Saya mencoba saran Anda namun komputasi masih mengembalikan 1 bahkan setelah mengubah nilai di kolom B menggunakan df.loc [2, 'B'] = 4,5. mungkin saya hanya bingung pada perhitungannya
Dr. DOOM
@ Dr. DOOM: Sulit membantu karena saya tidak tahu kode Anda. Apakah saya memahami dengan benar bahwa contoh saya di atas kembali 1dalam kasus Anda, bukan 0.99586?
Cleb
1
@Cleb: Nah, dalam konteks di mana saya bekerja, setiap indeks multi-kolom tingkat yang lebih tinggi memiliki sub-lapisan yang identik. Lihat pertanyaan ini untuk apa yang saya coba lakukan: stackoverflow.com/questions/57513002/…
Adrian Keister
7

Saya mengalami masalah yang sama. Itu tampak Citable Documents per Personseperti pelampung, dan python melompati entah bagaimana secara default. Semua kolom lain dari kerangka data saya dalam format numpy, jadi saya menyelesaikannya dengan mengonversi kolom menjadinp.float64

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

Ingat itu persis kolom yang Anda hitung sendiri

Gary
sumber
6

Solusi saya adalah setelah mengonversi data ke tipe numerik:

Top15[['Citable docs per Capita','Energy Supply per Capita']].corr()
ibozkurt79.dll
sumber
memilih kolom dan kemudian menerapkan metode .corr () adalah pilihan yang baik karena kita dapat menghitung korelasi berpasangan antara lebih dari 2 kolom
Sébastien Wieckowski
4

Jika Anda menginginkan korelasi antara semua pasangan kolom, Anda dapat melakukan sesuatu seperti ini:

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')])
mgoldwasser.dll
sumber
3

Saat Anda menyebutnya:

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

Karena, fungsi DataFrame.corr () melakukan korelasi berpasangan, Anda memiliki empat pasangan dari dua variabel. Jadi, pada dasarnya Anda mendapatkan nilai diagonal sebagai korelasi otomatis (korelasi dengan dirinya sendiri, dua nilai karena Anda memiliki dua variabel), dan dua nilai lainnya sebagai korelasi silang satu vs yang lain dan sebaliknya.

Lakukan korelasi antara dua rangkaian untuk mendapatkan satu nilai:

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)

atau, jika Anda menginginkan satu nilai dari fungsi yang sama (koreksi DataFrame):

single_value = correlation[0][1] 

Semoga ini membantu.

aumpen
sumber
3

Ini bekerja seperti ini:

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'])
Orca
sumber
1

Saya memecahkan masalah ini dengan mengubah tipe datanya. Jika Anda melihat 'Energy Supply per Capita' adalah tipe numerik sedangkan 'Citable docs per Capita' adalah tipe objek. Saya mengubah kolom menjadi float menggunakan astype. Saya memiliki masalah yang sama dengan beberapa fungsi np: count_nonzerodan sumbekerja sementara meandan stdtidak.

TAWARAN
sumber
0

mengubah 'Citable docs per Capita' menjadi numerik sebelum korelasi akan menyelesaikan masalah.

    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')
moinul hossain
sumber