Pandas透视表(pivot_table)详解

1,853 阅读5分钟

什么是透视表

透视表是由3部分构成的:
<1> index
<2> 列columns
<3> 值values

透视表是一种可以对数据动态排布并且分类计算汇总的表格格式。
或许大多数人都在Excel使用过数据透视表,也体会到它的强大功能,而在pandas中它被称作pivot_table。

透视表:就是对数据进行分组,然后对组内数据进行计算。分组可以有2个维度。
虽然pivot_table()函数非常有用,但是我发现为了能输出我所需要的内容,经常需要记住它的使用语法。

pivot_table()的语法格式:
    pivot_table(data_df,
                index=None,    # 即按照什么进行行分组
                columns=None,  # 也是按照什么进行列分组,该参数是可选的,不是必要的参数
                values=None,   # 对哪一列数据进行处理,如果没有该参数,则默认是对所有的列进行均值计算
                aggfunc=np.mean,  # 对数据具体做的处理函数,默认是进行均值运算
                fill_value=None,  # 如果出现空值,如何填充
                margins=False,  # 是否进行总计处理,,这里的总计包括行的总计和列的总计,其中列的总计的前提是columns属性有传入的字段
                dropna=True,
                margins_name='All')  # margins_name默认是"All",我们可以任意修改名字
     从该函数中可以知道,aggfunc默认是计算均值的,margins=False,默认是不进行汇总的。margins_name默认是'ALL',当然我们可以更改名字

reset_index() 和reset_index(drop=True)

reset_index() 
# 对dataframe对象重新设置index索引(默认是递增),原来的index保留

reset_index(drop=True) 
# 对dataframe对象重新设置index索引(默认是递增),原来的index删除
 
 

pivot_table()函数的margins参数

该参数的作用是:是否计算总计
margins=1,margins_name="总计":
<1> 当有index参数的时候,下面就会有总计
<2> 当有columns参数的时候,右边就会有总计
<3> 当index参数和columns参数都有的时候,下面和右边都会有总计
 
 是否有行和列,只是决定了下面或者右边有没有总计,但是不能决定有几个总计,,,至于有几个总计,是由value的值决定的。有1个value,右边就会有1个总计,有2个value,右边就会有2个总计,,,下面始终都是有一个总计。
 

pd.concat()函数

pd.concat([df1,df2],sort=True)
# 其中的sort参数的作用是:上下合并完之后,是否对列进行排序
# 比如一个列叫"a",另一个列叫"b",如果sort=True,则对列进行排序,a在前,b在后,
# 如果sort=False,则不对列进行排序,df1中的列是啥顺序的,最后合并完之后就是啥顺序的。
# 建议设置sort=False,因为这样可以减小计算的消耗

解释一下上图中"category",是pandas中的一种数据类型,是由固定的且有限数量的变量组成的,即是离散的,这种数据类型一般具有某种程度上的变化,或者具有某种顺序
比如:
    <1> 很好,好,较好,较差,差    # 这是一种程度上的变化
    <2> 开发,联调,测试,上线     # 这是一种顺序

 df["Status"] = df["Status"].astype("category")
 df["Status"].cat.set_categories(["won","pending","presented","declined"],inplace=True)
 以上2句代码的意思是:
     因为字段Status是有某种程度变化的字段,我们不能按照之前的排序方式进行排序(sort_values()),,所以我们需要先把该字段变成category类型
     然后用cat.set_categories()函数确定顺序,这样我们后续在进行透视表的时候,如果把Status作为index,那么得到的结果就是按照我们的顺序出现。
     
处理数据
    既然我们对数据做透视表,我觉得最容易的方法就是一步一个脚印地进行。
    添加项目和检查每一步来验证你正一步一步得到期望的结果。为了查看什么样的外观最能满足你的需要,就不要害怕处理顺序和变量的繁琐。

    最简单的透视表必须有一个索引index和一个数据帧valuesindex可以只有一个字段,也可以有多个字段,values同理
    在本例中,我们将使用“Name(名字)”列作为我们的索引。
    
以下3张图中,我们只是指定了index参数,没有指定values参数,在这种情况下,pivot_table()函数会默认将除了index之外的列作为value,并计算均值

# 下面这张图中,有一个参数是fill_value,之前很少用到。
# 在做透视表的时候,有的时候会出现空值,我们可以对这些空值进行填充,但是在填充之前,我们需要了解这些数据,用什么数值填充会比较合适。

# 下面这张图中,有一个参数是margins=True,其作用是进行总计,margins_name='xxx',就是起一个名字

# 上面说过,values参数可以有多列,,如我们想要对不同的列进行不同的处理,则需传入一个字典,通过kv的方式,对不同的列做不同的处理。

总结

最后,通过一张图来总结一下pd.pivot_table()函数

pivot_table vs. groupby

pivot_table()和groupby()的区别 
<1> pd.pivot_table(df,index=字段1,values=字段2,aggfunc=[函数],fill_value=0)
<2> df.groupby(字段1)字段2.agg(函数).fillna(0)
上面两个函数完全等价,pivot_table仿佛是加入了columnsmargin功能的groupby函数,比groupby更加灵活。