2013-09-04 17 views
5

Pandaları kullanarak, iki farklı işlevden hesaplanmış değerleri içeren tek bir çapraz tablolama (veya pivot tablo) hesaplamak mümkün mü?pandalarda çapraz/pivot_table içinde iki farklı işlevi nasıl kullanılır?

import pandas as pd 
import numpy as np 

c1 = np.repeat(['a','b'], [50, 50], axis=0) 
c2 = list('xy'*50) 
c3 = np.repeat(['G1','G2'], [50, 50], axis=0) 
np.random.shuffle(c3) 
c4=np.repeat([1,2], [50,50],axis=0) 
np.random.shuffle(c4) 
val = np.random.rand(100) 

df = pd.DataFrame({'c1':c1, 'c2':c2, 'c3':c3, 'c4':c4, 'val':val}) 

frequencyTable = pd.crosstab([df.c1,df.c2],[df.c3,df.c4]) 
meanVal = pd.crosstab([df.c1,df.c2],[df.c3,df.c4],values=df.val,aggfunc=np.mean) 

Yani, satırlar ve sütunlar hem her iki tabloda aynı, ama ne gibi gerçekten istiyorum frekanslar ve ortalama değerler hem bir tablodur:

c3   G1      G2   
c4  1    2    1    2 
c1 c2 freq val  freq val  freq val  freq val   
a x 6 0.624931 5 0.582268 8 0.528231 6 0.362804 
    y 7 0.493890 8 0.465741 3 0.613126 7 0.312894 
b x 9 0.488255 5 0.804015 6 0.722640 5 0.369480 
    y 6 0.462653 4 0.506791 5 0.583695 10 0.517954 
+0

'aggfunc = [func1, func2]' kullanmayı denediniz mi? Bunun işe yarayıp yaramadığına dair hiçbir fikrim yok ama sanırım onu ​​bir yerlerde görebildim. – Brian

+0

@Brian: Evet, sadece joris cevabını denedim ve harika çalışıyor! Çok teşekkürler! – HappyPy

+1

Sadece yorumlarımı yanıt olarak göndermem gerekir :-p – Brian

cevap

10

Bir verebilir fonksiyonların listesi: sorunuza gösterildiği gibi tabloyu istiyorsanız

pd.crosstab([df.c1,df.c2], [df.c3,df.c4], values=df.val, aggfunc=[len, np.mean]) 

, sen seviyeleri biraz yeniden düzenlemek zorunda kalacak:

In [42]: table = pd.crosstab([df.c1,df.c2], [df.c3,df.c4], values=df.val, aggfunc=[len, np.mean]) 

In [43]: table 
Out[43]: 
     len    mean        
c3  G1  G2   G1     G2   
c4  1 2 1 2   1   2   1   2 
c1 c2              
a x  4 6 8 7 0.303036 0.414474 0.624900 0.425234 
    y  5 5 8 7 0.543363 0.480419 0.583499 0.637657 
b x 10 6 4 5 0.400279 0.436929 0.442924 0.287572 
    y  6 8 5 6 0.400427 0.623319 0.764506 0.408708 

In [44]: table.reorder_levels([1, 2, 0], axis=1).sort_index(axis=1) 
Out[44]: 
c3  G1       G2       
c4  1    2    1    2   
     len  mean len  mean len  mean len  mean 
c1 c2                
a x  4 0.303036 6 0.414474 8 0.624900 7 0.425234 
    y  5 0.543363 5 0.480419 8 0.583499 7 0.637657 
b x 10 0.400279 6 0.436929 4 0.442924 5 0.287572 
    y  6 0.400427 8 0.623319 5 0.764506 6 0.408708 
+0

Vay, bu kadar basit :) Çok teşekkürler! – HappyPy

+0

BTW, eriyik ile yeniden şekillendirirken "len" ve "ortalama" sütunlarını yapmak mümkün müdür? Denedim: pd.melt (table.reset_index(), id_vars = ['c1', 'c2']), ama "len" ve "ortalama" öğeleri ile "NaN" adlı bir sütun alıyorum. Teşekkürler! – HappyPy

+1

Tam olarak "kendi sütunları" ile ne demek istiyorsun? "Mean" ve "len" olan sütunların "c1", "c2", "c3", "c4" sütunlarını "df.groupby ([" c1 ") ile alacağınız bir sütunu olmasını istiyor musunuz? "c2", "c3", "c4"]) agregat ([len, np.mean]). reset_index() '? Bu durumda çaprazlama ve erime yoluyla doğrudan yapabilirsiniz. – joris

İlgili konular