修复含LASER_ON/OFF的CSV坐标差值计算Python脚本问题
问题描述
现有如下结构的CSV文件,包含
x-Koordinate、y-Koordinate和LASER列,其中LASER_ON/OFF行无坐标值:
,x-Koordinate,y-Koordinate,LASER 1,51.972,1433.401 2,,,LASER_ON 3,41.972,1433.401 4,41.972,1438.401 5,51.97,1438.401 6,,,LASER_OFF 7,51.972,1382.401 8,,,LASER_ON 9,41.972,1382.401
需求为计算每行坐标与前一个有效坐标行的差值(若前一行是LASER_ON/OFF指令,则取再前的有效坐标值),例如:
3,((X line 3) - (X line 1) = new X line 3), ((Y line 3) - (Y line1) = new Y line 3) 4,((X line 4) - (X line 3) = new X line 4), ((Y line 4) - (Y line3) = new Y line 4)
原Python pandas脚本在无LASER指令时可正常运行,但包含LASER行时失效,原代码如下:
import pandas as pd def subtract_previous_value(csv_file): df = pd.read_csv(csv_file) if 'x-Koordinate' not in df.columns or 'y-Koordinate' not in df.columns: print("Error: The CSV file must have 'x-Koordinate' and 'y-Koordinate' columns.") return first_row = df[['x-Koordinate', 'y-Koordinate']].iloc[0:1] df['X-Koordinate'] = df['x-Koordinate'] - df['x-Koordinate'].shift(1) df['Y-Koordinate'] = df['y-Koordinate'] - df['y-Koordinate'].shift(1) df = df.drop(['x-Koordinate', 'y-Koordinate'], axis=1) df.loc[0, 'X-Koordinate'] = first_row['x-Koordinate'].iloc[0] df.loc[0, 'Y-Koordinate'] = first_row['y-Koordinate'].iloc[0] print("Original DataFrame:") print(df) df.to_csv(new_csv_file, index=False) print(f"\nResult saved to {new_csv_file}") subtract_previous_value(end_csv_file)
修复后的解决方案
问题核心是原脚本用shift(1)仅取上一行值,遇到LASER空行时无法定位最近的有效坐标行。修复思路是利用**向前填充(ffill)**获取每行的最近有效前置坐标,再进行差值计算,同时保留LASER指令内容。
修复后的完整代码:
import pandas as pd def subtract_previous_value(csv_file, new_csv_file): # 读取CSV并保留原始行号索引 df = pd.read_csv(csv_file, index_col=0) df.index.name = 'index' # 检查必要列是否存在 required_cols = ['x-Koordinate', 'y-Koordinate'] if not all(col in df.columns for col in required_cols): print(f"Error: CSV必须包含{'和'.join(required_cols)}列") return # 创建临时列,用向前填充获取最近的有效前置坐标 df['prev_x'] = df['x-Koordinate'].ffill() df['prev_y'] = df['y-Koordinate'].ffill() # 仅在当前行有有效坐标时计算差值,LASER行留空 df['X-Koordinate'] = df.apply( lambda row: row['x-Koordinate'] - row['prev_x'] if pd.notna(row['x-Koordinate']) and pd.notna(row['y-Koordinate']) else pd.NA, axis=1 ) df['Y-Koordinate'] = df.apply( lambda row: row['y-Koordinate'] - row['prev_y'] if pd.notna(row['x-Koordinate']) and pd.notna(row['y-Koordinate']) else pd.NA, axis=1 ) # 处理第一行有效坐标:保留原始值,不计算差值 first_valid_idx = df[pd.notna(df['x-Koordinate'])].index[0] df.loc[first_valid_idx, 'X-Koordinate'] = df.loc[first_valid_idx, 'x-Koordinate'] df.loc[first_valid_idx, 'Y-Koordinate'] = df.loc[first_valid_idx, 'y-Koordinate'] # 清理临时列,保留输出需要的列 output_cols = ['X-Koordinate', 'Y-Koordinate', 'LASER'] df = df[output_cols] # 打印结果并保存到新CSV print("处理后的结果:") print(df) df.to_csv(new_csv_file) print(f"\n结果已保存到 {new_csv_file}") # 调用示例,替换为你的文件路径 subtract_previous_value("input.csv", "output.csv")
关键修复点说明
- 向前填充(ffill):自动将最近的非空坐标值填充到后续空行,确保有效行能获取到正确的前置坐标。
- 条件差值计算:通过
apply判断当前行是否为有效坐标行,仅在有坐标时计算差值,LASER行保持空值。 - 鲁棒性处理:自动定位第一行有效坐标,即使CSV开头有LASER行也能正常处理。
- 保留原始行号:读取时指定
index_col=0,避免输出时丢失原始行号。
输出示例
处理后的CSV内容如下:
index,X-Koordinate,Y-Koordinate,LASER 1,51.972,1433.401, 2,,,,LASER_ON 3,-10.0,0.0, 4,0.0,5.0, 5,9.998,0.0, 6,,,,LASER_OFF 7,0.002,-56.0, 8,,,,LASER_ON 9,-10.0,0.0,
内容的提问来源于stack exchange,提问作者volk.SWAG.en
相关产品推荐
相关产品推荐

