Pandas索引比较报Lengths must match错如何匹配DataFrame长度
报错根因
执行索引比较时触发Lengths must match to compare,是因为比较运算符两侧的序列长度不匹配,pandas无法完成对齐运算:
- 左侧
df.index是原DataFrame全量行的索引,示例中长度为6 - 右侧
df[df.a == 5].index是筛选a列值为5的行后得到的子集索引,示例中长度仅为2 - 两个长度不一致的序列直接做
>比较,不符合pandas序列运算的对齐规则,因此直接抛错。
从给出的预期结果反推,实际要实现的逻辑是:每出现一次a列值为5的行,从该行开始往后的所有行的b列值减1。
正确实现代码
不需要做不等长索引比较,用累计计数的方式生成和原DataFrame等长的减数序列即可,逻辑简洁且不会出现长度不匹配问题,属于向量化运算,运行效率更高:
import pandas as pd import numpy as np df = pd.DataFrame( [[0, 10], [5, 10], [0, 10], [5, 10], [0, 10], [0, 10]], columns=["a", "b"] ) # 逐行累计到当前位置为止a列等于5的出现次数,返回序列和原df长度完全一致 cum_adjust = (df["a"] == 5).cumsum() # 直接对b列做逐行减法 df["b"] -= cum_adjust
执行后打印df即可得到预期结果:
a b 0 0 10 1 5 9 2 0 9 3 5 8 4 0 8 5 0 8
如果一定要沿用布尔索引筛选后做减法的思路,可以对每个a=5的索引位置单独生成等长掩码、逐次调整,逻辑更直观但运行效率低于累计计数方案:
for target_idx in df[df.a == 5].index: m = df.index >= target_idx df.loc[m, 'b'] -= 1
运行结果和预期完全一致。
内容的提问来源于stack exchange,提问作者Lance
相关产品推荐
相关产品推荐

