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

多列DataFrame处理连续1计数触发KeyError:-1的原因与解决方法

DataFrame连续1转递增数值的实现问题

需求说明

需将DataFrame中连续的1转换为递增数值(连续的1依次变为1、2、3…,0保持不变),示例如下:

输入DataFrame

print(df)
Out[1]: 
    Numbers
0         0
1         1
2         1
3         1
4         1
5         0
6         0
7         1
8         0
9         1
10        1

期望输出

print(dfo)
Out[2]: 
    Numbers
0         0
1         1
2         2
3         3
4         4
5         0
6         0
7         1
8         0
9         1
10        2

当前问题

通过嵌套循环结合loc判断逻辑实现时,单列DataFrame可正常运行,但扩展至多列DataFrame时触发KeyError: -1,报错信息如下:

File "C:\Users\talls\.conda\envs\Spyder\lib\site-packages\pandas\core\indexes\range.py", line 393, in get_loc
    raise KeyError(key) from err

KeyError: -1

问题解答

1. 错误产生的原因

核心问题是**loc是标签索引,而默认RangeIndex(行索引从0开始)不支持-1作为标签**。
你的循环逻辑中大概率存在类似df.loc[i-1, col]的代码:当处理某一列的第一行(i=0)且该值为1时,会尝试访问标签为-1的行,但RangeIndex的标签只有0、1、2...,没有-1,因此触发KeyError。单列时可能刚好第一行是0,不需要访问前一行,所以没报错;多列时总有列的第一行是1,触发了这个问题。

2. 修复方案

有两种简单的修复思路:

  • 边界判断+标签索引:在访问前一行前先检查i是否大于0,避免出现i-1=-1的情况,示例逻辑如下:
    for col in df.columns:
        count = 0
        for i in range(len(df)):
            if df.loc[i, col] == 1:
                # 第一行的1直接初始化为1,否则前一行是1则递增计数
                if i == 0 or df.loc[i-1, col] != 1:
                    count = 1
                else:
                    count += 1
                df.loc[i, col] = count
            else:
                count = 0
    
  • 改用位置索引iloc:iloc支持通过位置偏移访问行,iloc[i-1]可正确获取前一行,但同样需要配合边界判断避免逻辑错误。

3. 更优实现方式

嵌套循环效率极低(尤其是大数据量场景),推荐用pandas矢量化操作,无需循环即可实现需求:

def process_col(col):
    # 生成分组键:当值从非1变为1时,分组ID递增
    groups = (col != 1).cumsum()
    # 对每个分组内的1进行累计计数,0保持不变
    return col.where(col == 0, col.groupby(groups).cumcount() + 1)

# 对所有列应用处理函数
dfo = df.apply(process_col)

这个方法利用cumsum()生成连续1的分组,再通过groupby().cumcount()实现组内递增计数,完全矢量化,性能比循环提升几个数量级,同时天然支持多列处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 01:05:19