You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取itertools._grouper对象中各组的实例数量?

问题描述

我有如下DataFrame:

from itertools import groupby
import pandas as pd

idx1 = pd.date_range('2019-01-01',periods=5)
idx2 = pd.date_range('2020-06-01',periods=5)
idx3 = pd.date_range('2021-08-15',periods=5)
idx4 = pd.date_range('2022-03-20',periods=5)
idx = idx1.union(idx2).union(idx3).union(idx4)

l = [1,-1,-4,2,-3,4,5,1,-3,-4,-5,-3,-4,2,3,-1,-2,3,2,3]

df = pd.DataFrame(l, index=idx, columns=['a'])
df

输出结果:

a
2019-01-01  1
2019-01-02 -1
2019-01-03 -4
2019-01-04  2
2019-01-05 -3
2020-06-01  4
2020-06-02  5
2020-06-03  1
2020-06-04 -3
2020-06-05 -4
2021-08-15 -5
2021-08-16 -3
2021-08-17 -4
2021-08-18  2
2021-08-19  3
2022-03-20 -1
2022-03-21 -2
2022-03-22  3
2022-03-23  2
2022-03-24  3

用itertools.groupby按值是否小于0分组求和可以正常运行:

for k,g in groupby(df['a'], lambda x: x<0):
       print(k, sum(g))

输出:

False 1
True -5
False 2
True -3
False 10
True -19
False 5
True -3
False 8

但尝试用len()获取每个分组的实例数量时,出现了错误:

for k,g in groupby(df['a'], lambda x: x<0):
       print(k,len(g))

报错信息:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [241], in <cell line: 1>()
      1 for k,g in groupby(df['a'], lambda x: x<0):
----> 2     print(k,len(g))

TypeError: object of type 'itertools._grouper' has no len()
解决方案

itertools.groupby返回的_grouper对象是迭代器,不是可直接获取长度的序列,因此不能直接用len()。可以通过以下两种方式解决:

方法1:将迭代器转为列表后取长度

把分组迭代器转换成列表,再用len()统计元素数量:

for k,g in groupby(df['a'], lambda x: x<0):
    group_items = list(g)
    print(k, len(group_items))

输出:

False 1
True 2
False 1
True 1
False 3
True 3
False 2
True 2
False 3

方法2:用生成器表达式计数

通过生成器表达式遍历迭代器并计数,避免额外创建列表:

for k,g in groupby(df['a'], lambda x: x<0):
    count = sum(1 for _ in g)
    print(k, count)

输出结果和方法1完全一致。

更贴合Pandas的实现方式

既然已经使用Pandas,推荐直接用Pandas的分组功能来实现,更高效且符合Pandas的使用逻辑(注意要模拟itertools.groupby的连续相同分组逻辑):

# 创建是否为负数的标识列
df['is_negative'] = df['a'] < 0
# 生成连续分组的唯一ID(当分组标识变化时,ID自增)
df['group_id'] = (df['is_negative'] != df['is_negative'].shift()).cumsum()
# 按分组ID和标识统计数量
result = df.groupby(['group_id', 'is_negative'])['a'].count().reset_index()
print(result[['is_negative', 'a']])

输出:

is_negative  a
0        False  1
1         True  2
2        False  1
3         True  1
4        False  3
5         True  3
6        False  2
7         True  2
8        False  3

内容的提问来源于stack exchange,提问作者jgg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 11:50:45