Pandas使用loc赋值时报multi-index选择器与值长度不匹配错误如何解决
错误触发原因
- 赋值两边长度不匹配:你右侧使用
dfc1.loc[1].values得到的是长度为1的数组,但左侧d.loc[条件, 'Start']筛选出来的符合条件的行数通常不等于1,Pandas无法自动对齐长度就会抛出该错误。本质是你没有把右侧的取值转换为单个标量,导致Pandas误认为你要按数组长度逐行对应赋值。 - 区间判断逻辑错误:后续多个赋值行的条件存在笔误,比如
(d['Y'] > yo*4) & (d['Y'] > yo*5),两个大于判断等同于仅保留大于yo*5的记录,缺失了上限约束,你实际需要的是左开右开的区间判断,应该写为(d['Y'] > N*yo) & (d['Y'] < (N+1)*yo)。
代码修改方案
方案1:修正原逻辑的错误点
将dfc1改为一维Series简化取值,同时修正所有区间判断逻辑,右侧直接取标量赋值即可触发广播,不会出现长度不匹配的问题:
import pandas as pd import numpy as np xo = 6.5625 yo = 5.66 # 改为一维Series,避免DataFrame取值的维度问题 dfc1 = pd.Series([0.001,0.002,0.002,0.002,0.003,0.004,0.004,0.004,0.002,0.002,0.002,0.001]) # 修正条件和右侧取值,直接取标量即可广播到所有符合条件的行 d.loc[(d['X'] < xo) & (d['Y'] < yo), 'Start'] = dfc1[0] d.loc[(d['X'] < xo) & (d['Y'] > yo) & (d['Y'] < yo*2), 'Start'] = dfc1[1] d.loc[(d['X'] < xo) & (d['Y'] > yo*2) & (d['Y'] < yo*3), 'Start'] = dfc1[2] d.loc[(d['X'] < xo) & (d['Y'] > yo*3) & (d['Y'] < yo*4), 'Start'] = dfc1[3] d.loc[(d['X'] < xo) & (d['Y'] > yo*4) & (d['Y'] < yo*5), 'Start'] = dfc1[4] d.loc[(d['X'] < xo) & (d['Y'] > yo*5) & (d['Y'] < yo*6), 'Start'] = dfc1[5] d.loc[(d['X'] < xo) & (d['Y'] > yo*6) & (d['Y'] < yo*7), 'Start'] = dfc1[6] d.loc[(d['X'] < xo) & (d['Y'] > yo*7) & (d['Y'] < yo*8), 'Start'] = dfc1[7] d.loc[(d['X'] < xo) & (d['Y'] > yo*8) & (d['Y'] < yo*9), 'Start'] = dfc1[8] d.loc[(d['X'] < xo) & (d['Y'] > yo*9) & (d['Y'] < yo*10), 'Start'] = dfc1[9] d.loc[(d['X'] < xo) & (d['Y'] > yo*10) & (d['Y'] < yo*11), 'Start'] = dfc1[10] d.loc[(d['X'] < xo) & (d['Y'] > yo*11) & (d['Y'] < yo*12), 'Start'] = dfc1[11]
方案2:更简洁的向量化写法(推荐)
使用pd.cut直接对Y列做分箱映射取值,无需重复写判断条件,代码更简洁也不容易出现笔误:
import pandas as pd import numpy as np xo = 6.5625 yo = 5.66 # 定义分箱边界和对应的Start取值 bins = [0] + [yo*i for i in range(1, 13)] start_values = [0.001,0.002,0.002,0.002,0.003,0.004,0.004,0.004,0.002,0.002,0.002,0.001] # 筛选X<xo的行后直接分箱赋值 d.loc[d['X'] < xo, 'Start'] = pd.cut( d.loc[d['X'] < xo, 'Y'], bins=bins, labels=start_values, include_lowest=True ).astype(float)
内容的提问来源于stack exchange,提问作者JayRSP
相关产品推荐
相关产品推荐

