如何遍历pandas分组中的当前组与下一组配对?
问题:遍历DataFrame分组并获取当前组与下一组的配对
我有一个分组后的DataFrame:
import pandas as pd df = pd.DataFrame({'a': [0, 0, 1, 1, 2], 'b': range(5)}) g = df.groupby('a')
遍历分组的输出如下:
for key, gr in g: print(gr, '\n') a b 0 0 0 1 0 1 a b 2 1 2 3 1 3 a b 4 2 4
我需要完成一项计算,需要用到每个组及其下一个组(最后一组无需处理)。在这个示例中,我希望得到两组配对:
# 第一组配对: a b 0 0 0 1 0 1 a b 2 1 2 3 1 3 # 第二组配对: a b 2 1 2 3 1 3 a b 4 2 4
我的尝试
如果把分组存储在列表里,实现起来很简单:
lst = list(g) for x, x_next in zip(lst, lst[1:]): # 执行计算逻辑 ...
但pd.DataFrameGroupBy对象不支持切片操作:
g[1:] # 报错:TypeError: unhashable type: 'slice'(它误以为我要按列名访问) g.iloc[1:] # 报错:AttributeError: 'DataFrameGroupBy' object has no attribute 'iloc'
相关问题没有解决我的问题,我自己能写一个解决方案,但想知道有没有更优、更高效的实现方式(比如pandas原生方法?)
解决方案
方法1:将分组转为列表后遍历
这是最直接的方式,先把分组对象转为包含(键, 子DataFrame)的列表,再用zip配对当前组和下一组:
import pandas as pd df = pd.DataFrame({'a': [0, 0, 1, 1, 2], 'b': range(5)}) g = df.groupby('a') group_list = list(g) for (curr_key, curr_grp), (next_key, next_grp) in zip(group_list, group_list[1:]): print("当前组:") print(curr_grp) print("下一组:") print(next_grp) print("---")
输出:
当前组: a b 0 0 0 1 0 1 下一组: a b 2 1 2 3 1 3 --- 当前组: a b 2 1 2 3 1 3 下一组: a b 4 2 4 ---
方法2:利用分组键的顺序生成配对(适合分组键可排序的场景)
如果分组键是有序的,可以先获取所有分组键,再通过键来索引对应的组:
keys = list(g.groups.keys()) for i in range(len(keys)-1): curr_key = keys[i] next_key = keys[i+1] curr_grp = g.get_group(curr_key) next_grp = g.get_group(next_key) # 执行计算逻辑 print(f"当前组键:{curr_key}") print(curr_grp) print(f"下一组键:{next_key}") print(next_grp) print("---")
这种方式不需要把所有组都加载到内存,适合数据量较大的场景,因为get_group是按需取组。
方法3:用itertools的pairwise(Python 3.10+)
如果你的Python版本是3.10及以上,可以用itertools.pairwise来简化配对逻辑:
from itertools import pairwise for (curr_key, curr_grp), (next_key, next_grp) in pairwise(g): print("当前组:") print(curr_grp) print("下一组:") print(next_grp) print("---")
pairwise会自动生成连续的元素对,省去手动切片列表的步骤,代码更简洁。
内容的提问来源于stack exchange,提问作者Vladimir Fokow
相关产品推荐
相关产品推荐

