提问人:HappyPy 提问时间:9/5/2013 最后编辑:cottontailHappyPy 更新时间:11/14/2023 访问量:15784
如何在 pandas 的交叉表/pivot_table中使用两种不同的功能?
How to use two different functions within crosstab/pivot_table in pandas?
问:
使用 pandas,是否可以计算包含从两个不同函数计算的值的单个交叉表(或数据透视表)?
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)
因此,两个表中的行和列都是相同的,但我真正想要的是一个同时具有频率和平均值的表:
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
答:
15赞
joris
9/5/2013
#1
您可以给出函数列表:
pd.crosstab([df.c1,df.c2], [df.c3,df.c4], values=df.val, aggfunc=[len, np.mean])
如果您想要问题中所示的表格,则必须稍微重新排列级别:
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赞
HappyPy
9/6/2013
顺便说一句,在用熔体重塑时,是否有可能制作自己的“len”和“mean”柱?我试过:pd.melt(table.reset_index(), id_vars=['c1','c2']),但我得到了一个名为“NaN”的列,其中“len”和“mean”作为元素。谢谢!
1赞
joris
9/6/2013
你说的“自己的专栏”到底是什么意思?您是否想要一列带有“mean”和一列带有“len”的列,旁边是“c1”、“c2”、“c3”、“c4”列,就像您得到的那样?在这种情况下,您可以直接进行,而不是通过交叉表和熔化。df.groupby(["c1", "c2", "c3", "c4"]).aggregate([len, np.mean]).reset_index()
评论
aggfunc=[func1,func2]