Pandalar DataFrame'den ısı haritası oluşturma


112

Python'un Pandas paketinden oluşturulmuş bir veri çerçevem ​​var. Pandas paketinden DataFrame kullanarak nasıl ısı haritası oluşturabilirim?

import numpy as np 
from pandas import *

Index= ['aaa','bbb','ccc','ddd','eee']
Cols = ['A', 'B', 'C','D']
df = DataFrame(abs(np.random.randn(5, 4)), index= Index, columns=Cols)

>>> df
          A         B         C         D
aaa  2.431645  1.248688  0.267648  0.613826
bbb  0.809296  1.671020  1.564420  0.347662
ccc  1.501939  1.126518  0.702019  1.596048
ddd  0.137160  0.147368  1.504663  0.202822
eee  0.134540  3.708104  0.309097  1.641090
>>> 

Bir ısı haritası veya araştırma oluşturmak açısından ne denediniz? Daha fazlasını bilmeden, verilerinizi dönüştürmenizi ve bu yöntemi kullanmanızı
öğrenci

@joelostblom Bu bir cevap değil, yorum, ancak sorun şu ki, yorum yapacak kadar itibarım yok. Matris ve orijinal dizinin çıktı değeri tamamen farklı olduğu için biraz şaşkınım. Isı haritasına gerçek değerleri yazdırmak istiyorum, biraz farklı değil. Birisi bana bunun neden olduğunu açıklayabilir mi? Örneğin: * orijinal indekslenmiş veri: aaa / A = 2.431645 * ısı haritasındaki yazdırılan değerler: aaa / A = 1.06192
Monitotier

@Monitotier Lütfen yeni bir soru sorun ve denediğiniz şeyin eksiksiz bir kod örneğini ekleyin. Neyin yanlış olduğunu anlamanıza yardımcı olacak birini bulmanın en iyi yolu budur! Alakalı olduğunu düşünüyorsanız bu soruya bağlantı verebilirsiniz.
joelostblom

Yanıtlar:


82

İstersiniz matplotlib.pcolor:

import numpy as np 
from pandas import DataFrame
import matplotlib.pyplot as plt

index = ['aaa', 'bbb', 'ccc', 'ddd', 'eee']
columns = ['A', 'B', 'C', 'D']
df = DataFrame(abs(np.random.randn(5, 4)), index=index, columns=columns)

plt.pcolor(df)
plt.yticks(np.arange(0.5, len(df.index), 1), df.index)
plt.xticks(np.arange(0.5, len(df.columns), 1), df.columns)
plt.show()

Bu şunu verir:

Çıktı örneği


5
Buradapcolor vs. ile ilgili bazı ilginç tartışmalar varimshow .
LondonRob

1
… Ve ayrıca pcolormeshbu tür grafikler için optimize edilmiş.
Eric O Lebigot

180

Bugün buna bakan insanlar için, buradaheatmap() belgelendiği gibi Seaborn'u tavsiye ederim .

Yukarıdaki örnek şu şekilde yapılacaktır:

import numpy as np 
from pandas import DataFrame
import seaborn as sns
%matplotlib inline

Index= ['aaa', 'bbb', 'ccc', 'ddd', 'eee']
Cols = ['A', 'B', 'C', 'D']
df = DataFrame(abs(np.random.randn(5, 4)), index=Index, columns=Cols)

sns.heatmap(df, annot=True)

%matplotlibAşina olmayanlar için bir IPython sihirli işlevi nerede .


Neden pandaları kullanmıyorsun?
tommy.carstensen

9
Seaborn ve Pandalar birlikte güzel bir şekilde çalışır, bu nedenle verilerinizi doğru şekle sokmak için yine de Pandaları kullanırsınız. Seaborn, statik çizelgelerde uzmanlaşmıştır ve Pandas DataFrame'den bir ısı haritası yapmayı çok basit hale getirir.
Brideau

Görünüşe göre bu bağlantı kesilmiş; günceller misin !? Ayrıca yukarıdaki kodu nasıl çalıştırırım import matplotlib.pyplot as plt?
Cleb

Hey @Cleb, onu arşivlenmiş sayfaya güncellemem gerekiyor çünkü herhangi bir yere benzemiyor. Pyplot ile kullanmak için belgelerine bir göz atın: stanford.edu/~mwaskom/software/seaborn-dev/tutorial/…
Brideau

Olay örgüsünü gerçekten görmek için import matplotlib.pyplot as pltyerine kullanın %matplotlib inlineve ile bitirin plt.show().
tsveti_iko

83

Her söz için bir grafiğe ihtiyacınız yoksa ve değerleri bir tablo biçiminde temsil etmek için renk eklemekle ilgileniyorsanız style.background_gradient(), pandalar veri çerçevesi yöntemini kullanabilirsiniz . Bu yöntem, örneğin JupyterLab Notebook'ta pandalar veri çerçevelerini görüntülerken görüntülenen HTML tablosunu renklendirir ve sonuç, elektronik tablo yazılımında "koşullu biçimlendirme" kullanımına benzer:

import numpy as np 
import pandas as pd


index= ['aaa', 'bbb', 'ccc', 'ddd', 'eee']
cols = ['A', 'B', 'C', 'D']
df = pd.DataFrame(abs(np.random.randn(5, 4)), index=index, columns=cols)
df.style.background_gradient(cmap='Blues')

görüntü açıklamasını buraya girin

Ayrıntılı kullanım için, lütfen daha önce aynı konuda verdiğim daha ayrıntılı yanıta ve pandalar belgelerinin stil bölümüne bakın .


4
Kahretsin, bu cevap aslında aradığım cevap. IMO, daha yüksek (+1) olmalıdır.
ponadto

7
Bu cevap, gönderilen soru için geçerli bir çözüm değildir. Pandaların arka plan gradyan rengi, her satırı veya her sütunu ayrı ayrı dikkate alırken, matplotlib'in pcolor veya pcolormesh renklendirmesi tüm matrisi hesaba katar. Örneğin, aşağıdaki kod pd.DataFrame([[1, 1], [0, 3]]).style.background_gradient(cmap='summer') , her biri farklı renkte olan iki adet bir tabloyla sonuçlanır.
Toni Penya-Alba

4
@ ToniPenya-Alba Soru, pcolor veya pcolormesh davranışının nasıl kopyalanacağı değil, pandalar veri çerçevesinden bir ısı haritasının nasıl oluşturulacağıyla ilgili. İkincisi ile kendi amaçlarınız için ilgileniyorsanız, kullanabilirsiniz axis=None(pandalar 0.24.0'dan beri).
joelostblom

2
@joelostblom Yorumumu "bir aracı veya başka bir davranışı yeniden üretme" gibi kastetmedim, ancak "genellikle her satır / sütun için farklı ölçeklere sahip olmak yerine matristeki tüm öğelerin aynı ölçeği takip etmesini ister" gibi. Sizin de belirttiğiniz gibi, axis=Nonebunu başarır ve bence cevabınızın bir parçası olmalıdır (özellikle belgelenmediği için 0 )
Toni Penya-Alba

2
@ ToniPenya-Alba Yukarıya bağladığım axis=Noneayrıntılı cevabın bir kısmını diğer birkaç seçenekle birlikte zaten yaptım çünkü bu seçeneklerin bazılarının genel olarak istenen davranışları sağladığına katılıyorum. Ayrıca dün dokümantasyon eksikliğini fark ettim ve bir PR açtım .
joelostblom

17

Yararlı sns.heatmapapi burada . Parametreleri kontrol edin, çok sayıda var. Misal:

import seaborn as sns
%matplotlib inline

idx= ['aaa','bbb','ccc','ddd','eee']
cols = list('ABCD')
df = DataFrame(abs(np.random.randn(5,4)), index=idx, columns=cols)

# _r reverses the normal order of the color map 'RdYlGn'
sns.heatmap(df, cmap='RdYlGn_r', linewidths=0.5, annot=True)

görüntü açıklamasını buraya girin


4

Bir Pandas DataFrame'den etkileşimli bir ısı haritası istiyorsanız ve bir Jupyter dizüstü bilgisayarı çalıştırıyorsanız, etkileşimli Widget Clustergrammer-Widget'ı deneyebilirsiniz, burada NBViewer'daki etkileşimli not defterine bakın , dokümantasyon buradan

görüntü açıklamasını buraya girin

Daha büyük veri kümeleri için, geliştirme aşamasında olan Clustergrammer2 WebGL widget'ını deneyebilirsiniz (örnek not defteri burada )


1
vay bu çok temiz! python'a gelen bazı güzel paketler görmek güzel - R sihirlerini kullanmaktan yoruldum
Sos

2

Lütfen yazarlarının seabornyalnızca kategorik veri çerçeveleriyle çalışmak istediklerini seaborn.heatmap unutmayın. Genel değil.

Dizininiz ve sütunlarınız sayısal ve / veya tarih saat değerleriyse, bu kod size iyi hizmet edecektir.

Matplotlib ısı haritalama işlevi , endeksler yerine bölmelerpcolormesh gerektirir , bu nedenle veri çerçevesi endekslerinizden kutular oluşturmak için bazı süslü kodlar vardır (dizininiz eşit aralıklı olmasa bile!).

Gerisi basitçe np.meshgridve plt.pcolormesh.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def conv_index_to_bins(index):
    """Calculate bins to contain the index values.
    The start and end bin boundaries are linearly extrapolated from 
    the two first and last values. The middle bin boundaries are 
    midpoints.

    Example 1: [0, 1] -> [-0.5, 0.5, 1.5]
    Example 2: [0, 1, 4] -> [-0.5, 0.5, 2.5, 5.5]
    Example 3: [4, 1, 0] -> [5.5, 2.5, 0.5, -0.5]"""
    assert index.is_monotonic_increasing or index.is_monotonic_decreasing

    # the beginning and end values are guessed from first and last two
    start = index[0] - (index[1]-index[0])/2
    end = index[-1] + (index[-1]-index[-2])/2

    # the middle values are the midpoints
    middle = pd.DataFrame({'m1': index[:-1], 'p1': index[1:]})
    middle = middle['m1'] + (middle['p1']-middle['m1'])/2

    if isinstance(index, pd.DatetimeIndex):
        idx = pd.DatetimeIndex(middle).union([start,end])
    elif isinstance(index, (pd.Float64Index,pd.RangeIndex,pd.Int64Index)):
        idx = pd.Float64Index(middle).union([start,end])
    else:
        print('Warning: guessing what to do with index type %s' % 
              type(index))
        idx = pd.Float64Index(middle).union([start,end])

    return idx.sort_values(ascending=index.is_monotonic_increasing)

def calc_df_mesh(df):
    """Calculate the two-dimensional bins to hold the index and 
    column values."""
    return np.meshgrid(conv_index_to_bins(df.index),
                       conv_index_to_bins(df.columns))

def heatmap(df):
    """Plot a heatmap of the dataframe values using the index and 
    columns"""
    X,Y = calc_df_mesh(df)
    c = plt.pcolormesh(X, Y, df.values.T)
    plt.colorbar(c)

Kullanarak arayın heatmap(df)ve kullanarak görün plt.show().

görüntü açıklamasını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.