欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

51 pivot_table数据透视表(tcy)

程序员文章站 2024-02-13 16:56:46
...
 数据透视表

1.函数
 pd.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean',
               fill_value=None, margins=False, dropna=True, margins_name='All')
============================================================
2.实例

from io import StringIO
data='    No  Name  Rep  Manager  Product  Quantity  Account Price  Status \n' \
     '  0  120  汤姆  乔丹     布什        摩托      1           200         1.1  OK        \n' \
     '  1  121  约翰  乔丹     布什        摩托      2           210         1.2  NG        \n' \
     '  2  122  张三  贺龙     朱德        摩托      3           220         1.3  OK        \n' \
     '  3  123  张三  贺龙     朱德        汽车      4           230         1.4  NG        \n' \
     '  4  124  王东  叶挺     朱德        摩托      5           240         1.5  OK        \n' \
     '  5  125  张兵  张飞     刘备        宝剑      6           250         1.6  NG             '

columns = ['No', 'Name', 'Rep', 'Manager', 'Product', 'Quantity', 'Account', 'Price', 'Status']
df=pd.read_csv(StringIO(data), sep=r'\s+',names=columns,header=0)#保持列名有序
df["Status"] = df["Status"].astype("category")#加快速度

def sort_columnName(columnName):#定义列排序函数
       s=pd.Series(np.arange(9),index=columns)
       return s[columnName].sort_values().index

============================================================
实例1.1:index=["Name"]:使用Name列作为索引

df1=pd.pivot_table(df,index=["Name"])
df1[sort_columnName(df1.columns)]

            No  Quantity  Account  Price
Name
张三    122.5       3.5      225   1.35#名称重复 3项数据改变
张兵    125.0       6.0      250   1.60
汤姆    120.0       1.0      200   1.10
王东    124.0       5.0      240   1.50
约翰    121.0       2.0      210   1.20

实例1.2:index=["Name"], aggfunc='first'
df1=pd.pivot_table(df,index=["Name"], aggfunc='first')#返回首个重复值
df1[sort_columnName(df1.columns)]

       No Rep Manager Product  Quantity  Account  Price Status
Name
张三    122  贺龙      朱德      摩托         3      220    1.3     OK
张兵    125  张飞      刘备      宝剑         6      250    1.6     NG
汤姆    120  乔丹      布什      摩托         1      200    1.1     OK
王东    124  叶挺      朱德      摩托         5      240    1.5     OK
约翰    121  乔丹      布什      摩托         2      210    1.2     NG

实例1.3:index=["Name","Rep","Manager"]多个索引
df1=pd.pivot_table(df,index=["Name","Rep","Manager"])
df1[sort_columnName(df1.columns)]

                                 No  Quantity  Account  Price
Name Rep Manager
张三   贺龙  朱德       122.5       3.5      225   1.35
张兵   张飞  刘备       125.0       6.0      250   1.60
汤姆   乔丹  布什       120.0       1.0      200   1.10
王东   叶挺  朱德       124.0       5.0      240   1.50
约翰   乔丹  布什       121.0       2.0      210   1.20

实例1.3:通过将“Rep”列和“Manager”列进行对应分组,来实现数据聚合和总结
df1=pd.pivot_table(df,index=["Manager","Rep"])
df1[sort_columnName(df1.columns)]

                         No  Quantity  Account  Price
Manager Rep
刘备      张飞   125.0       6.0      250   1.60
布什      乔丹   120.5       1.5      205   1.15
朱德      叶挺   124.0       5.0      240   1.50
             贺龙   122.5       3.5      225   1.35

============================================================
实例2.:values=["Price"]
Account”和“Quantity”列对于我们来说并没什么用。
 利用“values”域显式地定义我们关心的列,就可以实现移除那些不关心的列。

pd.pivot_table(df,index=["Manager","Rep"],values=["Price"])

                        Price
Manager Rep
刘备      张飞    1.60
布什      乔丹    1.15
朱德      叶挺    1.50
             贺龙    1.35
# “Price”列会自动计算数据平均值

 ===========================================================
实例3.1:aggfunc=np.sum对该列元素进行计数或求和。
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],aggfunc=np.sum)

                       Price
Manager Rep
刘备      张飞     1.6
布什      乔丹     2.3
朱德      叶挺     1.5
             贺龙     2.7

实例3.2:
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],aggfunc=[np.mean,len])

                      mean   len
                      Price Price
Manager Rep
刘备      张飞   1.60   1.0
布什      乔丹   1.15   2.0
朱德      叶挺   1.50   1.0
             贺龙   1.35   2.0
 ===========================================================
列vs.值

如果我们想通过不同产品来分析销售情况,那么变量“columns”将允许我们定义一个或多个列。
我认为pivot_table中一个令人困惑的地方是“columns(列)”和“values(值)”的使用。
记住,变量“columns(列)”是可选的,它提供一种额外的方法来分割你所关心的实际值。
然而,聚合函数aggfunc最后是被应用到了变量“values”中你所列举的项目上。

 实例4.:columns
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],
                       columns=["Product"],aggfunc=[np.sum])

                    sum
                    Price
Product        宝剑   摩托   汽车
Manager Rep
刘备      张飞    1.6  NaN  NaN
布什      乔丹    NaN  2.3  NaN
朱德      叶挺    NaN  1.5  NaN
             贺龙    NaN  1.3  1.4

实例5.1:fill_value=0NaN移除用

pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],
               columns=["Product"],aggfunc=[np.sum],fill_value=0)

                    sum
                    Price
Product        宝剑   摩托   汽车
Manager Rep
刘备      张飞    1.6  0.0  0.0
布什      乔丹    0.0  2.3  0.0
朱德      叶挺    0.0  1.5  0.0
             贺龙    0.0  1.3  1.4

实例5.2:添加“Quantity”列
pd.pivot_table(df,index=["Manager","Rep"],values=["Price","Quantity"],
                       columns=["Product"],aggfunc=[np.sum],fill_value=0)

                    sum
                    Price                      Quantity
Product        宝剑   摩托   汽车    宝剑 摩托 汽车
Manager Rep
刘备      张飞    1.6  0.0  0.0        6  0  0
布什      乔丹    0.0  2.3  0.0        0  3  0
朱德      叶挺    0.0  1.5  0.0        0  5  0
             贺龙    0.0  1.3  1.4        0  3  4

实例5.3:我们将“Product”从“columns”中移除,并添加到“index”变量中。
 pd.pivot_table(df,index=["Manager","Rep","Product"],
                        values=["Price","Quantity"],aggfunc=[np.sum],fill_value=0)

                                 sum
                                 Price Quantity
Manager Rep Product
刘备      张飞  宝剑        1.6        6
布什      乔丹  摩托        2.3        3
朱德      叶挺  摩托        1.5        5
             贺龙  摩托        1.3        3
                      汽车        1.4        4

实例6:查看一些总和数据“margins=True”
 pd.pivot_table(df,index=["Manager","Rep","Product"],values=["Price","Quantity"],
                        aggfunc=[np.sum,np.mean],fill_value=0,margins=True)

                             sum                   mean
                             Price Quantity    Price Quantity
Manager Rep Product
刘备      张飞  宝剑        1.6        6  1.60      6.0
布什      乔丹  摩托        2.3        3  1.15      1.5
朱德      叶挺  摩托        1.5        5  1.50      5.0
             贺龙  摩托        1.3        3  1.30      3.0
                      汽车        1.4        4  1.40      4.0
All                                 8.1       21  1.35      3.5

实例7:margins=True让我们以更高的管理者角度来分析此渠道。
 根据我们前面对category的定义,注意现在“Status”是如何排序的。

 pd.pivot_table(df,index=["Manager","Status"],values=["Price"],
               aggfunc=[np.sum],fill_value=0,margins=True)

                         sum
                         Price
Manager Status
刘备      NG       1.6
布什      NG       1.2
             OK       1.1
朱德      NG       1.4
             OK       2.8
All                     8.1

实例8.1:
为了对你选择的不同值执行不同的函数,你可以向aggfunc传递一个字典。
 不过,这样做有一个副作用,那就是必须将标签做的更加简洁才行。
pd.pivot_table(df,index=["Manager","Status"],columns=["Product"],values=["Quantity","Price"],
                        aggfunc={"Quantity":len,"Price":np.sum},fill_value=0)
Out[265]:
                       Price                     Quantity
Product           宝剑   摩托   汽车  宝剑 摩托 汽车
Manager Status
刘备      NG       1.6  0.0  0.0        1  0  0
布什      NG       0.0  1.2  0.0        0  1  0
             OK       0.0  1.1  0.0        0  1  0
朱德      NG       0.0  0.0  1.4        0  0  1
             OK       0.0  2.8  0.0        0  2  0

实例8.2:
此外,你也可以提供一系列的聚合函数,并将它们应用到“values”中的每个元素上。
table = pd.pivot_table(df,index=["Manager","Status"],columns=["Product"],values=["Quantity","Price"],
                                  aggfunc={"Quantity":len,"Price":[np.sum,np.mean]},fill_value=0)

                     Price                                                Quantity
                     mean                   sum                      len
Product         宝剑  摩托  汽车  宝剑  摩托  汽车    宝剑 摩托 汽车
Manager Status
刘备      NG       1.6  0.0  0.0    1.6  0.0  0.0         1  0  0
布什      NG       0.0  1.2  0.0    0.0  1.2  0.0         0  1  0
             OK       0.0  1.1  0.0    0.0  1.1  0.0         0  1  0
朱德      NG       0.0  0.0  1.4    0.0  0.0  1.4         0  0  1
             OK       0.0  1.4  0.0    0.0  2.8  0.0         0  2  0

 经验法则:一旦你使用多个“grouby”,那么你需要评估此时使用透视表是否是一种好的选择。

============================================================
3.高级透视表过滤
一旦你生成了需要的数据,那么数据将存在于数据帧中。
 所以,你可以使用自定义的标准数据帧函数来对其进行过滤。

实例9.1:如果你只想查看一个管理者(例如朱德)的数据,可以这样:

 table.query('Manager == ["朱德"]')

                       Price                                                        Quantity
                       mean                     sum                            len
Product           宝剑   摩托   汽车   宝剑   摩托   汽车       宝剑 摩托 汽车
Manager Status
朱德      NG       0.0  0.0  1.4  0.0  0.0  1.4        0  0  1
             OK       0.0  1.4  0.0  0.0  2.8  0.0        0  2  0

实例9.2:我们可以查看所有的暂停(NG)和成功(OK)的交易,代码如下所示:
table.query('Status == ["OK","NG"]')

                       Price                                                        Quantity
                       mean                     sum                            len
Product           宝剑   摩托   汽车   宝剑   摩托   汽车       宝剑 摩托 汽车
Manager Status
刘备      NG       1.6  0.0  0.0          1.6  0.0  0.0        1  0  0
布什      NG       0.0  1.2  0.0          0.0  1.2  0.0        0  1  0
             OK       0.0  1.1  0.0          0.0  1.1  0.0        0  1  0
朱德      NG       0.0  0.0  1.4          0.0  0.0  1.4        0  0  1
             OK       0.0  1.4  0.0          0.0  2.8  0.0        0  2  0

这是pivot_table中一个很强大的特性,所以一旦你得到了你所需要的pivot_table格式的数据,
就不要忘了此时你就拥有了pandas的强大威力。

============================================================
参考
https://nbviewer.jupyter.org/url/pbpython.com/extras/Pandas-Pivot-Table-Explained.ipynb