Python创建DataFrame新列时索引错误问题求助
问题分析与修复方案
让我帮你拆解下你遇到的几个核心问题,以及对应的解决办法:
1. 循环中错误获取整列数据,而非当前行的值
你在循环里写的oldValueX = df_train['Location_X']是直接取了整个Location_X列的所有值(一个Series),而不是当前循环行的单个值。这会导致后续计算的结果是一个Series,无法直接赋值给单个单元格,进而引发索引不兼容的错误。
修正方式:改为获取当前行的对应值,比如用row['Location_X']或者df_train.loc[index, 'Location_X']。
2. rangeValues字典存在逻辑错误
仔细看你的rangeValues里,'lab1'的x_min是0.6,x_max是0.1,这会导致newMaxX - newMinX得到负数,最终转换后的Absolute_x会是反向的结果,这大概率不是你想要的。请检查这个范围的定义是否正确,应该保证x_max > x_min。
3. 更高效的实现方式:避免用iterrows循环
iterrows()在处理大型DataFrame时效率极低,推荐用Pandas的向量化操作或者apply()方法来实现,代码更简洁且性能更好。
修正后的代码(两种方式)
方式一:修复iterrows循环的问题
rangeValues = { 'gang': {"x_min" : 0.4, "x_max": 0.6, "y_min": 0, "y_max": 1}, 'lab1': {"x_min" : 0.1, "x_max": 0.6, "y_min": 0.09, "y_max": 0.3} # 修正x_min和x_max的顺序 } df_train['Absolute_x'] = 0 df_train['Absolute_y'] = 0 for index, row in df_train.iterrows(): # 获取当前行的单个值,而非整列 oldValueX = row['Location_X'] oldValueY = row['Location_Y'] oldMin = 0 oldMax = 1 location = row['Location'] # 从字典中取当前location对应的范围 ranges = rangeValues[location] newMaxX = ranges['x_max'] newMinX = ranges['x_min'] newMaxY = ranges['y_max'] newMinY = ranges['y_min'] # 计算并赋值给当前行 df_train.at[index, 'Absolute_x'] = (((oldValueX - oldMin) * (newMaxX - newMinX)) / (oldMax - oldMin)) + newMinX df_train.at[index, 'Absolute_y'] = (((oldValueY - oldMin) * (newMaxY - newMinY)) / (oldMax - oldMin)) + newMinY df_train.head()
方式二:用apply实现(更推荐)
import pandas as pd rangeValues = { 'gang': {"x_min" : 0.4, "x_max": 0.6, "y_min": 0, "y_max": 1}, 'lab1': {"x_min" : 0.1, "x_max": 0.6, "y_min": 0.09, "y_max": 0.3} } def calculate_absolute(row): oldMin = 0 oldMax = 1 ranges = rangeValues[row['Location']] # 计算Absolute_x abs_x = ((row['Location_X'] - oldMin) * (ranges['x_max'] - ranges['x_min'])) / (oldMax - oldMin) + ranges['x_min'] # 计算Absolute_y abs_y = ((row['Location_Y'] - oldMin) * (ranges['y_max'] - ranges['y_min'])) / (oldMax - oldMin) + ranges['y_min'] return pd.Series([abs_x, abs_y], index=['Absolute_x', 'Absolute_y']) # 直接生成两列,无需提前初始化 df_train[['Absolute_x', 'Absolute_y']] = df_train.apply(calculate_absolute, axis=1) df_train.head()
关于之前的错误补充
ValueError: Incompatible indexer with Series:是因为你用了链式索引df_train[index]['Absolute_x'],这种方式容易引发Pandas的索引警告,且当index是整数时,可能会和位置索引混淆。正确的单个单元格赋值应该用df_train.at[index, 'Absolute_x']或者df_train.loc[index, 'Absolute_x']。set_value方法已经被废弃,所以推荐用at或loc来替代。
内容的提问来源于stack exchange,提问作者Maxime Callebaut
相关产品推荐
相关产品推荐

