Pandas 进阶知识学习

Pandas 进阶学习

导语

本部分主要记录分组聚合以及创建透视表和交叉表的方法,通过此部分的学习主要明白Pandas内部的数据结构以及统计函数是什么样子的程度即可。因为需求的多样,下面例子只是给出某种需求下的内容,实际处理数据会遇到更为复杂的情况,因此单看例子很难消化,深入了解需要结合具体例子进行相关操作。

Pandas分组聚合

分组聚合的流程主要有三步:

  • 分割步骤将DataFrame按照指定的键分割成若干组;
  • 应用步骤对每个组应用函数,通常是累计、转换或过滤函数;
  • 组合步骤将每一组的结果合并成一个输出数组。

img

分组

通常我们将数据分成多个集合的操作称之为分组,Pandas中使用groupby()函数来实现分组操作。

需要注意一点,分组返回的是groupby对象,输出时需要使用获取方法(get_group())获取。

Series系列分组

选取数据帧中的一列作为index进行分组:

import pandas as pd

data = {'A': [1, 2, 2, 3, 2, 4],
        'B': [2014, 2015, 2014, 2014, 2015, 2017],
        'C': ["a", "b", "c", "d", "e", "f"],
        'D': [0.5, 0.9, 2.1, 1.5, 0.5, 0.1]
        }
df = pd.DataFrame(data)

df["A"].groupby(df["B"])   #df的 A 列根据 B 进行分组  
通过数据类型或者字典分组

数据类型分组:

df.groupby(df.dtypes,axis=1)   # axis=1表示按列分组,以数据类型为列名  

传入字典分组:

dic = {"A": "number", "B": "number", "C": "str", "D": "number"}  
df.groupby(dic, axis=1)   #按列分组,列名是字典的值  
获取单个分组

使用get_group()方法可以选择一个组。

print(df.groupby("A").get_group(2))
'''
   A     B  C    D
1  2  2015  b  0.9
2  2  2014  c  2.1
4  2  2015  e  0.5'''
对分组进行迭代

GroupBy对象支持迭代,可以产生一组二元元组(由分组名和数据块组成)。

for name,data in df.groupby("A"):
    print(name)
    print(data)
'''
1
   A     B  C    D
0  1  2014  a  0.5
2
   A     B  C    D
1  2  2015  b  0.9
2  2  2014  c  2.1
4  2  2015  e  0.5
3
   A     B  C    D
3  3  2014  d  1.5
4
   A     B  C    D
5  4  2017  f  0.1'''

聚合

聚合函数为每个组返回单个聚合值。当创建了groupby对象,就可以对分组数据执行多个聚合操作。比较常用的是通过聚合函数或等效的agg方法聚合。

聚合简单说就是对组里面的数据进行运算等操作。

常用的聚合函数如下表:

函数名说明
count分组中非空值的数量
sum非空值的和
mean非空值的平均值
median非空值的中位数
std、var无偏标准差和方差
min、max非空值的最小和最大值
prod非空值的积
first、last第一个和最后一个非空值
应用单个聚合函数

对分组后的子集进行数值运算时,不是数值的列会自动过滤

import pandas as pd
import numpy as np

data = {'A': [1, 2, 2, 3, 2, 4],
        'B': [2014, 2015, 2014, 2014, 2015, 2017],
        'C': ["a", "b", "c", "d", "e", "f"],
        'D': [0.5, 0.9, 2.1, 1.5, 0.5, 0.1]
        }
df = pd.DataFrame(data)

print(df.groupby("B").sum())  
'''  A    D
B           
2014  6  4.1
2015  4  1.4
2017  4  0.1'''
应用多个聚合函数
print(df.groupby("B").agg([np.sum,np.mean,np.std]))
'''    A              D                    
     sum mean  std  sum      mean       std
B                                          
2014   6    2  1.0  4.1  1.366667  0.808290
2015   4    2  0.0  1.4  0.700000  0.282843
2017   4    4  NaN  0.1  0.100000       NaN'''
自定义函数传入agg()中

我们可以自定义函数对对应数列进行相关操作。

def result(df):
    return df.max() - df.min()
print(df.groupby("B").agg(result))   #求每一组最大值与最小值的差  
'''   A    D
B           
2014  2  1.6
2015  0  0.4
2017  0  0.0'''
对不同的列使用不同的聚合函数

下面的例子根据列C进行了对对应列A,列B的值进行相关的聚合函数,并整合到列C。

mapping = {"A":np.sum,"B":np.mean}
print(df.groupby("C").agg(mapping)) 
''' A     B
C         
a  1  2014
b  2  2015
c  2  2014
d  3  2014
e  2  2015
f  4  2017'''

程序示例

上面的例子或许不够全面,单纯看可能并不能将其很好的应用,因此需要给出一个实例,以便更好的理解。

使用Pandas中的read_csv()函数读取step1/drinks.csv中的数据,数据的列名如下表所示,请根据continent分组并求每个大洲红酒消耗量的最大值与最小值的差以及啤酒消耗量的和。

列名说明
country国家名
beer_servings啤酒消耗量
spirit_servings白酒消耗量
wine_servings红酒消耗量
total_litres_of_pure_alcohol纯酒精总量
continent大洲名

示例程序

import pandas as pd
import numpy as np

def sub(df):
    return df.max() - df.min()

def main():
    data = pd.read_csv('step1/drinks.csv')
    df = pd.DataFrame(data)
    df1 = {"wine_servings": sub, "beer_servings": np.sum}
    print(df.groupby('continent').agg(df1))

if __name__ == '__main__':
    main()
'''
					wine_servings  beer_servings
continent                                  
Africa                   233           3258
Asia                     123           1630
Europe                   370           8720
North America             99           3345
Oceania                  212           1435
South America            220           2101
'''

Pandas创建透视表和交叉表

透视表与交叉表均为一种数据汇总使用的方法,根据实际情况使用,按需使用。

透视表

透视表是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行聚合,并根据行和列上得分组建将数据分配到各个矩形区域中。在pandas中,可以通过pivot_table函数创建透视表。

pivot_talbe函数的参数:

DataFrame.pivot_table(self, values=None, index=None, columns=None, ggfunc='mean',
                      fill_value=None,.margins = False, dropna = True, margins_name = 'All')
参数名说明
values待聚合的列的名称。默认聚合所有数值列
index用于分组的列名或其他分组键,出现在结果透视表的行
columns用于分组的列名或其他分组键,出现在结果透视表的列
aggfunc聚合函数或函数列表,默认为mean,可以是任何对groupby有效的函数
fill_value用于替换结果表中的缺失值
dropnaboolean值,默认为True
margins_namestring,默认为‘ALL’,当参数margins为True时,ALL行和列的名字

示例

import pandas as pd
import numpy as np

data = {'A': [1, 2, 2, 3, 2, 4],
        'B': [2014, 2015, 2014, 2014, 2015, 2017],
        'C': ["a", "b", "c", "d", "e", "f"],
        'D': [0.5, 0.9, 2.1, 1.5, 0.5, 0.1]
        }
df = pd.DataFrame(data)
print(df.pivot_table(index=["B"], columns=["C"], values=["A"], aggfunc=sum, margins=True))
'''     A                             
C       a    b    c    d    e    f All
B                                     
2014  1.0  NaN  2.0  3.0  NaN  NaN   6
2015  NaN  2.0  NaN  NaN  2.0  NaN   4
2017  NaN  NaN  NaN  NaN  NaN  4.0   4
All   1.0  2.0  2.0  3.0  2.0  4.0  14
'''

交叉表

交叉表是一种用于计算分组频率的特殊透视表。通常使用crosstab函数来创建交叉表。


crosstab的参数

pd.crosstab(index,columns,values=None,rownames=None  
colnames=None,aggfunc=None,margins=False,dropna=True,normalize=False)  

其中rownames可以设置行名,colnames可以设置列名,而且前两个参数可以是数组、Series或数组列表。


示例

import pandas as pd
import numpy as np

data = {'A': [1, 2, 2, 3, 2, 4],
        'B': [2014, 2015, 2014, 2014, 2015, 2017],
        'C': ["a", "b", "c", "d", "e", "f"],
        'D': [0.5, 0.9, 2.1, 1.5, 0.5, 0.1]
        }
df = pd.DataFrame(data)
print(pd.crosstab(index=[df["B"],df["A"]], columns=df["C"], values=df["A"], aggfunc=sum, margins=True))
'''
C         a    b    c    d    e    f  All
B    A                                   
2014 1  1.0  NaN  NaN  NaN  NaN  NaN    1
     2  NaN  NaN  2.0  NaN  NaN  NaN    2
     3  NaN  NaN  NaN  3.0  NaN  NaN    3
2015 2  NaN  2.0  NaN  NaN  2.0  NaN    4
2017 4  NaN  NaN  NaN  NaN  NaN  4.0    4
All     1.0  2.0  2.0  3.0  2.0  4.0   14'''

程序示例

使用Pandas中的read_csv函数加载step2/tip.csv文件中的数据集,分别用透视表和交叉表统计顾客在每种用餐时间(time)每个星期下(day)小费(tip)总和情况。数据集列名信息如下表:

列名说明
total_bill消费总账单
tip小费金额
day消费日期(星期几)
time用餐时间段(早、中、晚)
size吸烟数量
import pandas as pd

#创建透视表
def create_pivottalbe(data):
    return data.pivot_table(index=["day"], columns=["time"],values=["tip"],aggfunc=sum,margins=True)

#创建交叉表
def create_crosstab(data):
    return pd.crosstab(index=[data.day],columns=[data.time],values=data.tip,aggfunc=sum, margins=True)  

def main():
    #读取csv文件数据并赋值给data
    data = pd.read_csv('step2/tip.csv')
    piv_result = create_pivottalbe(data)
    cro_result = create_crosstab(data)
    print("透视表:\n{}".format(piv_result))
    print("交叉表:\n{}".format(cro_result))

if __name__ == '__main__':
    main()
    
'''
透视表:
         tip                
time  Dinner   Lunch     All
day                         
Fri    35.28   16.68   51.96
Sat   260.40     NaN  260.40
Sun   247.39     NaN  247.39
Thur    3.00  168.83  171.83
All   546.07  185.51  731.58
交叉表:
time  Dinner   Lunch     All
day                         
Fri    35.28   16.68   51.96
Sat   260.40     NaN  260.40
Sun   247.39     NaN  247.39
Thur    3.00  168.83  171.83
All   546.07  185.51  731.58'''
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值