如何在Pandas中用if-elif-else按Side值生成矩形角点并解决真值歧义报错
错误原因
你遇到的ValueError是因为判断条件书写错误:if df['Side']=='S1'中的df['Side']是Series类型,哪怕你筛选后的子集只有1行,df['Side']=='S1'返回的也是布尔类型的Series,而Python的if判断需要单个布尔值,pandas无法确定该判断「所有元素为真」「任意元素为真」还是其他逻辑,因此抛出歧义错误。
另外你存在一处笔误:things = list(set(df1.Thing.unique()))按你给出的示例数据,得到的结果应该是['A','B'],而非['S1','S2'],后者是Side列的取值范围。
解决方案1:修正原有遍历逻辑
只需要修改判断条件取Side列的单个值,同时把concat操作移到循环外提升性能即可:
dd = [] ee = [] things = df1['Thing'].unique() for thing in things: df = df1[df1['Thing'] == thing] # 取当前子集的Side值 side = df['Side'].iloc[0] if side == 'S1': a = df.join(df.apply(lambda r: pd.Series({'corner_x': [r['x']+r['length_x']/2, r['x']-r['length_x']/2], 'corner_y': [r['y'], r['y']-r['length_y']/2],}), axis=1).explode('corner_x').explode('corner_y'), how='right') ee.append(a) elif side == 'S2': b = df.join(df.apply(lambda r: pd.Series({'corner_x': [r['x']+r['length_x']/2, r['x']-r['length_x']/2], 'corner_y': [r['y']+r['length_y']/2, r['y']+r['length_y']/2],}), axis=1).explode('corner_x').explode('corner_y'),how='right') dd.append(b) # concat操作移到循环外 EE = pd.concat(ee, ignore_index=True) DD = pd.concat(dd, ignore_index=True) Full = pd.concat([EE,DD], ignore_index=True)
解决方案2:更简洁的无遍历写法
无需循环遍历Thing,直接对全表每行做处理,根据每行的Side值走对应计算逻辑,代码更简洁、性能更高:
def calc_corners(r): corner_x = [r['x'] + r['length_x']/2, r['x'] - r['length_x']/2] if r['Side'] == 'S1': corner_y = [r['y'], r['y'] - r['length_y']/2] else: corner_y = [r['y'] + r['length_y']/2, r['y'] + r['length_y']/2] return pd.Series({'corner_x': corner_x, 'corner_y': corner_y}) Full = df1.join( df1.apply(calc_corners, axis=1).explode('corner_x').explode('corner_y'), how='right' ).reset_index(drop=True)
内容的提问来源于stack exchange,提问作者Serge de Gosson de Varennes
相关产品推荐
相关产品推荐

