2014-07-07 43 views
2

我有一個熊貓數據框中的多維數據,其中一個變量指示類。例如,下面是我的嘗試與不良-地圖熱圖散點圖:用熊貓計算和繪製計數比率

import pandas as pd 
import random 
import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.cm import get_cmap 

nrows=1000 
df=pd.DataFrame([[random.random(), random.random()]+[random.randint(0, 1)] for _ in range(nrows)], 
       columns=list("ABC")) 

bins=np.linspace(0, 1, 20)   
df["Abin"]=[bins[i-1] for i in np.digitize(df.A, bins)] 
df["Bbin"]=[bins[i-1] for i in np.digitize(df.B, bins)] 

g=df.ix[:,["Abin", "Bbin"]+["C"]].groupby(["Abin", "Bbin"]) 
data=g.agg(["sum", "count"]) 
data.reset_index(inplace=True) 
data["classratio"]=data[("C", "sum")]/data[("C","count")] 

plt.scatter(data.Abin, data.Bbin, c=data.classratio, cmap=get_cmap("RdYlGn_r"), marker="s") 

我想了分級功能繪製班密度。現在我使用np.digitize進行分箱,並使用一些複雜的Python手工密度計算來繪製熱圖。

當然,這可以用熊貓(樞軸?)更緊湊地完成?你是否知道一種簡便的方法來組合這兩個特徵(例如間隔0 ... 1上的10個分檔),然後繪製一個分類密度熱圖,其中顏色表示該2D分檔內1與總行數之比?

+0

你能告訴我們你期望的和你嘗試過的代碼嗎? – jrjc

+0

你就是這麼說的:「我怎樣才能更簡單地用熊貓來做'xyz'?」但是不清楚'xyz'究竟是什麼......另外,就繪圖而言,做任何圖[這裏](http://matplotlib.org/gallery.html)看起來都接近你的射擊? –

回答

3

是的,可以在一個非常簡潔的方式使用構建完成在cut功能:

在[65]:

nrows=1000 
df=pd.DataFrame([[random.random(), random.random()]+[random.randint(0, 1)] for _ in range(nrows)], 
       columns=list("ABC")) 
In [66]: 
#This does the trick. 
pd.crosstab(np.array(pd.cut(df.A, 20)), np.array(pd.cut(df.B, 20))).values 
Out[66]: 
array([[2, 2, 2, 2, 7, 2, 3, 5, 1, 4, 2, 2, 1, 3, 2, 1, 7, 2, 4, 2], 
     [1, 2, 4, 2, 0, 3, 3, 3, 1, 1, 2, 1, 4, 3, 2, 1, 1, 2, 2, 1], 
     [0, 4, 1, 3, 1, 3, 2, 5, 2, 3, 1, 1, 1, 4, 2, 3, 6, 5, 2, 2], 
     [5, 2, 3, 2, 2, 1, 3, 2, 4, 0, 3, 2, 0, 4, 3, 2, 1, 3, 1, 3], 
     [2, 2, 4, 1, 3, 2, 2, 4, 1, 4, 3, 5, 5, 2, 3, 3, 0, 2, 4, 0], 
     [2, 3, 3, 5, 2, 0, 5, 3, 2, 3, 1, 2, 5, 4, 4, 3, 4, 3, 6, 4], 
     [3, 2, 2, 4, 3, 3, 2, 0, 0, 4, 3, 2, 2, 5, 4, 0, 1, 2, 2, 3], 
     [0, 0, 4, 4, 3, 2, 4, 6, 4, 2, 0, 5, 2, 2, 1, 3, 4, 4, 3, 2], 
     [3, 2, 2, 3, 4, 2, 1, 3, 1, 3, 4, 2, 4, 3, 2, 3, 2, 3, 4, 4], 
     [0, 1, 1, 4, 1, 4, 3, 0, 1, 1, 1, 2, 6, 4, 3, 5, 3, 3, 1, 4], 
     [2, 2, 4, 1, 3, 4, 1, 2, 1, 3, 3, 3, 1, 2, 1, 5, 2, 1, 4, 3], 
     [0, 0, 0, 4, 2, 0, 2, 3, 2, 2, 2, 4, 4, 2, 3, 2, 1, 2, 1, 0], 
     [3, 3, 0, 3, 1, 5, 1, 1, 2, 5, 6, 5, 0, 0, 3, 2, 1, 5, 7, 2], 
     [3, 3, 2, 1, 2, 2, 2, 2, 4, 0, 1, 3, 3, 1, 5, 6, 1, 3, 2, 2], 
     [3, 0, 3, 4, 3, 2, 1, 4, 2, 3, 4, 0, 5, 3, 2, 2, 4, 3, 0, 2], 
     [0, 3, 2, 2, 1, 5, 1, 4, 3, 1, 2, 2, 3, 5, 1, 2, 2, 2, 1, 2], 
     [1, 3, 2, 1, 1, 4, 4, 3, 2, 2, 5, 5, 1, 0, 1, 0, 4, 3, 3, 2], 
     [2, 2, 2, 1, 1, 3, 1, 6, 5, 2, 5, 2, 3, 4, 2, 2, 1, 1, 4, 0], 
     [3, 3, 4, 7, 0, 2, 6, 4, 1, 3, 4, 4, 1, 4, 1, 1, 2, 1, 3, 2], 
     [3, 6, 3, 4, 1, 3, 1, 3, 3, 1, 6, 2, 2, 2, 1, 1, 4, 4, 0, 4]]) 
In [67]: 

abins=np.linspace(df.A.min(), df.A.max(), 21) 
bbins=np.linspace(df.B.min(), df.B.max(), 21) 
Z=pd.crosstab(np.array(pd.cut(df.ix[df.C==1, 'A'], abins)), 
      np.array(pd.cut(df.ix[df.C==1, 'B'], bbins)), aggfunc=np.mean).div(
      pd.crosstab(np.array(pd.cut(df.A, abins)), 
         np.array(pd.cut(df.B, bbins)), aggfunc=np.mean)).values 
Z = np.ma.masked_where(np.isinf(Z),Z) 
x=np.linspace(df.A.min(), df.A.max(), 20) 
y=np.linspace(df.B.min(), df.B.max(), 20) 
X,Y=np.meshgrid(x, y) 
plt.contourf(X, Y, Z, vmin=0, vmax=1) 
plt.colorbar() 

enter image description here

plt.pcolormesh(X, Y, Z, vmin=0, vmax=1) 
plt.colorbar() 

enter image description here

+0

感謝您提供'剪切'和熱圖建議!雖然,似乎'crosstab'沒有做正確的事情?對於每個垃圾桶,我想繪製1和這個垃圾桶*內的總點*之間的比率。這就是爲什麼我把總和/計數分開的原因。這與'crosstab'有什麼不同?有'pivot'的簡潔解決方案嗎? – Gerenuk

+0

抱歉錯過了解您的問題。當然,你可以用類似的方法來做,只有0/0會導致'inf',我們需要使用一個掩碼數組來處理這個。看到更新的編輯。 –