您的位置:

Python中的groupby函数详解

一、groupby函数的基本介绍

Python中的groupby函数可以将相邻的元素按照指定的key值分组,返回一个分组完成后的迭代器。该函数可用于对数据进行分组分析,统计,排序等操作。 本文将围绕着groupby函数展开,详细介绍其用法和实现。

from itertools import groupby
    data = [1, 1, 2, 3, 3, 3]
    grouped = groupby(data)
    for k, g in grouped:
        print(k, list(g))

上述代码将列表[1, 1, 2, 3, 3, 3]按照元素相邻的方式分组,输出结果如下:

1 [1, 1]
2 [2]
3 [3, 3, 3]

二、groupby函数的常见应用场景

groupby函数常用于数据处理和分析。

1. 数据分组和统计计算

groupby函数可以将一组数据按照指定的标准进行分组,然后针对每个分组进行统计计算,得到不同分组的统计结果。

import pandas as pd
    data = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar',
                               'foo', 'bar', 'foo', 'foo'],
                         'B': ['one', 'one', 'two', 'three',
                               'two', 'two', 'one', 'three'],
                         'C': [1, 2, 3, 4, 5, 6, 7, 8],
                         'D': [9,10,11,12,13,14,15,16]})
    for name, group in data.groupby('A'):
        print(name)
        print(group)

上述代码将DataFrame对象根据‘A’列的取值进行分组,输出每个分组的名称及其内容。

2. 数据去重

相同的元素在被分组后会被统一归为一组,通过groupby函数可以实现对某个列表中相同元素的去重处理。

a = [1, 3, 2, 1, 2, 3, 12, 11, 12]
    b = list(set(a))
    print(b)
    c = [key for key, group in groupby(a)]
    print(c)

上述代码输出结果为 [1,2,3,11,12],这里的c变量是groupby函数去重后的结果。

三、groupby相关函数详解

1. groupby函数

groupby(iterable[,key]) 根据iterable中元素的key进行分组

2. itertools.groupby(iterable[, key][,func])

功能与groupby函数基本一致,可以在原来基础上添加func参数,该参数用于进行元素的函数映射。

3. sorted(iterable[,key])

该函数类似于groupby函数,不同之处在于sorted函数是将整个可迭代对象进行排序,而groupby函数只是针对相邻的元素进行分组,返回一个迭代器对象。

4. defaultdict(list)

在进行字典分组的时候,如果某个key没有对应的value,会报错。使用defaultdict可以解决这个问题。默认情况下defaultdict创建的字典的value是一个空的list。

from collections import defaultdict
    d = defaultdict(list)
    for key, value in data_list:
        d[key].append(value)

上述代码将元素按照key值分组,在字典中创建空列表作为value,然后将相同key的value添加到该列表中。

四、groupby的实现原理及优化方式

1. 实现原理

groupby函数的实现原理可以通过Itertools模块中的groupby函数源代码进行解读。

# groupby('AAAABBBCCDAABBB') --> A B C D A B
# groupby([1,2,1,2,3,1,2]) --> 1, 2, 1, 2, 3, 1, 2
def groupby(iterable, key=None):
    # groupby('AABBCD') -> A-A B-B C-C D-D
    # groupby('AaaBBbcCAAa', str.lower) -> A-a A-a A-a B-b b-C C-A A-a
    for k, g in groupby_impl(iterable, key):
        yield k, list(g)

def groupby_impl(iterable, key=None):
    # groupby('AABBCD') -> A-A B-B C-C D-D
    # groupby('AaaBBbcCAAa', str.lower) -> A-a A-a A-a B-b b-C C-A A-a
    it = iter(iterable)
    if key is None:
        key = lambda x: x
    sentinel = object()
    prev_key = sentinel
    prev_value = []
    for value in it:
        cur_key = key(value)
        if cur_key != prev_key:
            yield prev_key, (x for x in prev_value)
            prev_key = cur_key
            prev_value = [value]
        else:
            prev_value.append(value)
    yield prev_key, (x for x in prev_value)

通过源代码,可以发现groupby函数的实现原理:利用迭代器遍历输入的可迭代对象,通过定义的key函数将元素进行分组。

2. 优化方式

为了提高groupby函数的执行效率,可以采用以下优化方式:

① 对元素进行排序

在进行groupby函数分组之前,可以对元素进行排序操作,使得相同的元素可以更快地被分组。

# 数据进行排序
    data.sort(key=lambda x: x[0])
    groups = []
    uniquekeys = []
    for k, g in groupby(data, lambda x: x[0]):
        groups.append(list(g))    
        uniquekeys.append(k)
    # 排序后输出结果
    print(groups)
    print(uniquekeys)

② 利用集合去重

如果只需要去重和计数,可以使用集合替代groupby函数,它可以更快地完成去重和计数操作。

a = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
    b = set(a)
    for i in b:
        print(i, '出现次数:', a.count(i))

五、总结

本文详细介绍了Python中的groupby函数的用法和实现方式,包括groupby函数的常见应用场景、相关函数等内容,同时还介绍了groupby函数的实现原理及优化方式。在数据处理和分析中,掌握这个函数可以极大地提高数据的处理效率和准确度。