如何对DataFrame列进行分类计数并统计连续0的出现次数?
解决DataFrame中连续0的计数问题
我明白你的需求啦——要给DataFrame里的连续0组标记它们的总连续长度,遇到1的时候count列就设为0。咱们先看看你之前的方法为什么没达到预期,再一步步实现正确的效果。
你的尝试问题分析
你用df['No.'].ne(0).cumsum()来创建分组的思路是对的,这个操作会把连续的0分到同一个分组,每次遇到1就会生成新的分组。但后面直接用groupby(groups).count()或者agg(len)赋值时,会把所有分组的长度都赋值给对应行,包括全是1的分组——比如连续的1组成的分组长度是2,那这些行的count就会被设为2,而不是你想要的0,这就是问题所在。
正确的实现方法
我们需要在分组计算长度后,只保留0组的长度,把1组的长度替换为0。这里用transform方法可以很方便地把分组长度广播到每一行,再结合布尔值过滤就能实现需求:
import numpy as np import pandas as pd np.random.seed(2021) a = np.random.randint(0, 2, 20) df = pd.DataFrame(a, columns=['No.']) # 1. 创建分组标记:每次遇到1就开启新分组 groups = df['No.'].ne(0).cumsum() # 2. 计算每个分组的长度,仅保留0组的长度,1组设为0 df['count'] = df.groupby(groups)['No.'].transform('size') * df['No.'].eq(0).astype(int) print(df)
运行这段代码后,输出就会完全符合你的预期:
| No. | count | |
|---|---|---|
| 0 | 0 | 1 |
| 1 | 1 | 0 |
| 2 | 1 | 0 |
| 3 | 0 | 1 |
| 4 | 1 | 0 |
| 5 | 0 | 3 |
| 6 | 0 | 3 |
| 7 | 0 | 3 |
| 8 | 1 | 0 |
| 9 | 0 | 1 |
| 10 | 1 | 0 |
| 11 | 1 | 0 |
| 12 | 1 | 0 |
| 13 | 1 | 0 |
| 14 | 0 | 6 |
| 15 | 0 | 6 |
| 16 | 0 | 6 |
| 17 | 0 | 6 |
| 18 | 0 | 6 |
| 19 | 0 | 6 |
代码解释
df.groupby(groups)['No.'].transform('size'):这个操作会计算每个分组的行数,然后把这个数值填充到该分组的每一行,相当于给每个行标记了它所在分组的总长度。df['No.'].eq(0).astype(int):把No.列的0转换成1,1转换成0,这样和前面的分组长度相乘后,1所在的行就会变成0,0所在的行就会保留分组的总长度。
内容的提问来源于stack exchange,提问作者jaried
相关产品推荐
相关产品推荐

