谈谈 pandas中的数据处理利器:groupby

    技术2024-11-12  17

    转载自品略图书馆 http://www.pinlue.com/article/2020/07/0306/3710953839048.html

     

    在数据分析中,常常有这样的场景,需要对不同类别的数据,分别进行处理,然后再将处理之后的内容合并,作为结果输出。对于这样的场景,就需要借助灵活的groupby功能来处理。groupby的操作过程如下

    split,  第一步,根据某一个或者多个变量的组合,将输入数据分成多个group

    apply, 第二步, 对每个group对应的数据进行处理

    combine, 第三步,将分组处理的结果合并起来,形成一个新的数据

    图示如下

    上述例子在python中的实现过程如下

    >>> import numpy as np

    >>> import pandas as pd

    >>> df = pd.DataFrame({"x":["a","a","b","b","c","c"],"y":[2,4,0,5,5,10]})

    >>> df

    x y

    0 a 2

    1 a 4

    2 b 0

    3 b 5

    4 c 5

    5 c 10

    >>> df.groupby("x").mean()

    y

    x

    a 3.0

    b 2.5

    c 7.5上述代码实现的是分组求均值的操作,通过groupby方法,首选根据x标签的内容分为a,b,c3组,然后对每组求均值,最后将结果进行合并。

    groupby函数的返回值为为DataFrameGroupBy对象,有以下几个基本属性和方法

    >>> grouped = df.groupby("x")

    >>> grouped

    <pandas.core.groupby.generic.DataFrameGroupBy object at 0x06E94FA0>

    # groups属性,返回值为字典,key是分组的类别

    >>> grouped.groups

    {"a": Int64Index([0, 1], dtype="int64"), "b": Int64Index([2, 3], dtype="int64"), "c": Int64Index([4, 5], dtype="int64")}

    # len函数可以获得分组后的组别数

    >>> len(grouped.groups)

    3

    # get_group方法可以获得每个group对应的数据框

    >>> grouped.get_group("a")

    x y

    0 a 2

    1 a 4

    >>> grouped.get_group("b")

    x y

    2 b 0

    3 b 5

    # 遍历group

    >>> for name, group in grouped:

    ... print(name)

    ... print(group)

    ...

    a

    x y

    0 a 2

    1 a 4

    b

    x y

    2 b 0

    3 b 5

    c

    x y

    4 c 5

    5 c 10pandas中的groupby实际上非常的灵活且强大,具体的操作技巧有以下几种

    1. 分组方式分组的依据既可以是单个标签,也可以是多个标签的组合,示例如下

    >>> df = pd.DataFrame({"id":[1, 2, 3, 4],

    ... "class":["a","a","b","b"],

    ... "sex":["male", "female", "male", "female"],

    ... "age":[26, 16, 28, 30],

    ... })

    >>>

    >>> df

    id class     sex  age

    0   1     a male 26

    1   2     a female 16

    2   3     b male 28

    3   4     b female 30

    # 单个列标签进行分组

    >>> df.groupby("class")

    # 多个列标签的组合,用列表的形式声明

    >>> df.groupby(["class","sex"])

    # 用行标签分组

    >>> arrays = [["Falcon", "Falcon", "Parrot", "Parrot"],

    ... ["Captive", "Wild", "Captive", "Wild"]]

    >>> index = pd.MultiIndex.from_arrays(arrays, names=("Animal", "Type"))

    >>> df = pd.DataFrame({"Max Speed": [390., 350., 30., 20.]},

    ... index=index)

    >>> df

    Max Speed

    Animal Type

    Falcon Captive 390.0

    Wild 350.0

    Parrot Captive 30.0

    Wild 20.0

    # 针对行标签为multiindex的情况,用level指定分组的标签

    # 既可以是数字索引

    >>> df.groupby(level=0).mean()

    Max Speed

    Animal

    Falcon 370.0

    Parrot 25.0

    # 也可以是name属性

    >>> df.groupby(level="Type").mean()

    Max Speed

    Type

    Captive 210.0

    Wild 185.02. 分组处理分组处理就是对每个分组进行相同的操作,groupby的返回对象并不是一个DataFrame,   所以无法直接使用DataFrame的一些操作函数。

    针对一些常用的功能,groupby提供了一些函数来直接操作DataFrameGroupBy对象, 比如统计个数,求和,求均值等,示例如下

    # 计算每个group的个数

    >>> df.groupby("x").count()

    # 计算每个group的个数

    >>> df.groupby("x").size()

    # 求和

    >>> df.groupby("x").sum()

    # 求均值

    >>> df.groupby("x").mean()

    # 求中位数

    >>> df.groupby("x").median()

    # 求方差

    >>> df.groupby("x").var()

    # 求标准差

    >>> df.groupby("x").std()

    # 求最小值

    >>> df.groupby("x").min()

    # 求最大值

    >>> df.groupby("x").max()这里只是列举了部分函数,完整列表请参见API。通过aggregate方法则可以灵活的使用各种函数,用法如下

    >>> df = pd.DataFrame({"x":["a","a","b","b","c","c"],"y":[2,4,0,5,5,10]})

    # 一次使用一个函数进行处理

    >>> df.groupby("x").aggregate(np.mean)

    y

    x

    a 3.0

    b 2.5

    c 7.5

    # agg是aggregate的简写

    >>> df.groupby("x").agg(np.mean)

    y

    x

    a 3.0

    b 2.5

    c 7.5

    # 一次使用多种函数进行处理

    >>> df.groupby("x").agg([np.sum, np.mean])

    y

    sum mean

    x

    a 6 3.0

    b 5 2.5

    c 15 7.5

    # 自定义输出的列标签

    >>> df.groupby("x").agg([np.sum,np.mean]).rename(columns={"sum":"cus_sum","mean":"cus_mean"})

    y

    cus_sum cus_mean

    x

    a 6 3.0

    b 5 2.5

    c 15 7.5

    >>> df = pd.DataFrame({"x":["a","a","b","b","c","c"],"y":[2,4,0,5,5,10],"z":[4.0,2.1,3.5,4.2,3.8,4.7]})

    >>> df

    x y z

    0 a 2 4.0

    1 a 4 2.1

    2 b 0 3.5

    3 b 5 4.2

    4 c 5 3.8

    5 c 10 4.7

    # 同一列用不用函数进行处理

    >>> df.groupby("x").agg(min=("y", "min"), max=("y", "max"))

    min max

    x

    a 2 4

    b 0 5

    c 5 10

    # 不同列用不同函数进行处理

    >>> df.groupby("x").agg(min=("y", "min"), max=("z", "max"))

    min max

    x

    a 2 4.0

    b 0 4.2

    c 5 4.7

    # 不同列用不同函数进行处理

    >>> df.groupby("x").agg({"y":"mean","z":"sum"})

    y z

    x

    a 3.0 6.1

    b 2.5 7.7

    c 7.5 8.53. 分组过滤

    当需要根据某种条件对group进行过滤时,可以使用filter方法,用法如下

    >>> df = pd.DataFrame({"x":["a","a","b","b","c","c"],"y":[2,4,0,5,5,10]})

    >>> df

    x y

    0 a 2

    1 a 4

    2 b 0

    3 b 5

    4 c 5

    5 c 10

    >>> df.groupby("x").filter(lambda x: x.mean() > 2.5)

    x y

    0 a 2

    1 a 4

    4 c 5

    5 c 104. 汇总数据

    transform方法返回一个和输入的原始数据相同尺寸的数据框,常用于在原始数据框的基础上增加新的一列分组统计数据,用法如下

    >>> df = pd.DataFrame({"x":["a","a","b","b","c","c"],"y":[2,4,0,5,5,10]})

    >>> df

    x y

    0 a 2

    1 a 4

    2 b 0

    3 b 5

    4 c 5

    5 c 10

    # 输出结果的行数和输入的原始数据框相同

    # 内容为分组统计的结果

    >>> df.groupby("x").transform(lambda x:x.count())

    y

    0 2

    1 2

    2 2

    3 2

    4 2

    5 2

    # 通过索引操作符,在原始数据框的基础上添加汇总列

    >>> df["mean_size"] = df.groupby("x").transform(lambda x:x.count())

    >>> df

    x y mean_size

    0 a 2 2

    1 a 4 2

    2 b 0 2

    3 b 5 2

    4 c 5 2

    5 c 10 25. apply

    apply相比agg, 更加的灵活,用法如下

    >>> df = pd.DataFrame({"x":["a","a","b","b","c","c"],"y":[2,4,0,5,5,10]})

    >>> df

    x y

    0 a 2

    1 a 4

    2 b 0

    3 b 5

    4 c 5

    5 c 10

    >>> df.groupby("x").apply(lambda x:x.count())

    x y

    x

    a 2 2

    b 2 2

    c 2 2

    >>> df.groupby("x").apply(lambda x:x - x.count())

    y

    0 0

    1 2

    2 -2

    3 3

    4 3

    5 8pandas中的groupby功能非常的灵活强大,可以极大提高数据处理的效率。

    ·end·

    Processed: 0.013, SQL: 9