如何基于索引值在CSV间提取数据?代码运行后新文件无变化
问题分析与修复方案
问题描述
我需要筛选数据并基于筛选条件创建新CSV文件,但运行代码后目标文件Stage_3_try.csv没有任何变化。我使用enumerate获取索引值,将符合投影条件的数据写入新CSV,此前代码可正常运行,但加入循环后失效,相关代码如下:
# Projec import csv from csv import writer A = np.array([ 316143.8829, 6188926.04]) B = np.array([ 314288.7418, 6190277.519]) for i in range(0,len(east_3)): P = [] P.append(east_3[i]) P.append( north_3[i]) P = np.asarray(P) projected = point_on_line(P) #a code to do the projection x_values = [A[0], B[0]] y_values = [A[1], B[1]] plt.plot(x_values, y_values, 'b-') if projected[0]>315745.75 and projected[1]>6188289: with open('Stage_3_try.csv', 'a') as f_out: writer = csv.writer(f_out) for num, row in enumerate(stage_3['UTM North NAD83']): if row == P[1]: writer.writerow(stage_3.loc[[num][0]]) print(type(stage_3.loc[[num][0]])) plt.plot(projected[0], projected[1], 'rx') f_out.close() else: pass
PS: 我更新了代码,之前的版本可以正常工作,但加入循环后就失效了
核心问题排查
- 文件操作错误:
with语句会自动关闭文件,外层的f_out.close()会抛出异常,导致代码中断(若未捕获异常)。 - 浮点匹配精度问题:直接用
==比较浮点数(row == P[1]),极易因精度误差导致匹配失败,找不到目标行。 - 低效重复操作:每次满足条件都遍历整个列找匹配值,既浪费资源,又可能重复写入同一行;循环内重复绘制线段AB也是冗余操作。
- DataFrame写入格式错误:用
csv.writer写入pandas.Series时,会默认写入索引值,导致CSV格式混乱。
修复后的代码
假设stage_3是pandas DataFrame,优化后的代码如下:
import numpy as np import pandas as pd import matplotlib.pyplot as plt # 实现投影函数(示例逻辑,根据实际需求调整) def point_on_line(P): A = np.array([316143.8829, 6188926.04]) B = np.array([314288.7418, 6190277.519]) AP = P - A AB = B - A t = np.dot(AP, AB) / np.dot(AB, AB) t = np.clip(t, 0, 1) # 限制投影点在线段AB上 return A + t * AB # 初始化存储选中行的DataFrame selected_data = pd.DataFrame(columns=stage_3.columns) A = np.array([316143.8829, 6188926.04]) B = np.array([314288.7418, 6190277.519]) # 只绘制一次线段AB,避免循环内重复操作 plt.plot([A[0], B[0]], [A[1], B[1]], 'b-') # 用zip同时遍历east和north数组,代码更简洁 for east, north in zip(east_3, north_3): P = np.array([east, north]) projected = point_on_line(P) # 检查投影条件,同时处理浮点精度问题 if projected[0] > 315745.75 and projected[1] > 6188289: # 用np.isclose匹配浮点数,设置容差避免精度误差 matches = stage_3[np.isclose(stage_3['UTM North NAD83'], north, atol=1e-6)] selected_data = pd.concat([selected_data, matches], ignore_index=True) # 绘制投影点 plt.plot(projected[0], projected[1], 'rx') # 一次性写入CSV,避免重复文件操作,同时排除索引列 selected_data.to_csv('Stage_3_try.csv', index=False) plt.show()
关键修复点说明
- 移除错误的文件关闭:
with语句自动管理文件生命周期,无需手动调用close()。 - 解决浮点匹配问题:用
np.isclose代替==比较浮点数,设置合理容差,避免精度误差导致匹配失败。 - 批量收集后写入:先把所有符合条件的行收集到DataFrame,最后一次性写入CSV,提升效率并避免重复写入。
- 减少冗余操作:线段AB只绘制一次,循环内仅处理必要的数据筛选和投影点绘制。
- 验证条件触发:可在
if块内添加print(projected),确认是否有数据满足条件;若没有,检查投影函数实现或阈值设置是否正确。
内容的提问来源于stack exchange,提问作者Tahmina
相关产品推荐
相关产品推荐

