pandas DataFrame重复值检测及翼型坐标绘图多余连线处理
翼型坐标爬取绘图异常修复
问题复现
爬取公开翼型坐标数据的原始实现代码:
import pandas as pd from io import StringIO import requests import matplotlib.pyplot as plt import numpy as np from scipy.interpolate import make_interp_spline url = 'https://m-selig.ae.illinois.edu/ads/coord/b737a.dat' response = requests.get(url).text lines = [] for idx, line in enumerate(response.split('\n'), start=1): if all([x.replace('.','').replace('-','').isdecimal() for x in line.split()]): lines.append(line) lines = [x.split() for x in lines] df = pd.DataFrame(lines) df = df.dropna(axis=0) df = df.astype(float) df = df[~(df > 1).any(1)] print(df)
代码运行输出的坐标数据集:
0 1 2 0.0000 0.0177 3 0.0023 0.0309 4 0.0050 0.0372 5 0.0076 0.0415 6 0.0143 0.0499 7 0.0249 0.0582 8 0.0495 0.0730 9 0.0740 0.0814 10 0.0990 0.0866 11 0.1530 0.0907 12 0.1961 0.0905 13 0.2504 0.0887 14 0.3094 0.0858 15 0.3520 0.0833 16 0.3919 0.0804 17 0.4477 0.0756 18 0.5034 0.0696 19 0.5593 0.0626 20 0.5965 0.0575 21 0.6488 0.0498 22 0.8351 0.0224 23 0.9109 0.0132 24 1.0000 0.0003 26 0.0000 0.0177 27 0.0022 0.0038 28 0.0049 -0.0018 29 0.0072 -0.0053 30 0.0119 -0.0106 31 0.0243 -0.0204 32 0.0486 -0.0342 33 0.0716 -0.0457 34 0.0979 -0.0516 35 0.1488 -0.0607 36 0.1953 -0.0632 37 0.2501 -0.0632 38 0.2945 -0.0626 39 0.3579 -0.0610 40 0.3965 -0.0595 41 0.4543 -0.0563 42 0.5050 -0.0527 43 0.5556 -0.0482 44 0.6063 -0.0427 45 0.6485 -0.0375 46 0.8317 -0.0149 47 0.9410 -0.0053 48 1.0000 -0.0003
问题分析
绘图时出现跨区域多余连线,核心原因如下:
- 该站点翼型文件采用固定存储规则:先沿x轴从0到1记录翼型上表面坐标,到达尾缘点(x=1)后,再沿x轴从1回落至0记录翼型下表面坐标
- 直接按数据集原始顺序连线,下表面绘制完成回到前缘点(x=0)后,会自动和数据集开头的上表面前缘点连接,生成贯穿翼型内部的无效连线
- 观测到的
x=0重复值是上下表面各自的前缘起点,属于有效轮廓数据,直接删除会造成翼型形状缺失
修复逻辑
- 检测分界点:定位x列(第0列)第一次取值为1的索引位置,以此为界拆分上表面、下表面两个独立坐标集
- 重复值清理:对拆分后的两个数据集分别做重复值检测,删除单段轮廓内的重复坐标点,避免后续光滑插值时报错
- 绘图顺序重构:按「上表面从x=0到x=1,下表面反转后从x=1回到x=0」的顺序拼接坐标,去掉拼接处重复的尾缘点,保证绘图路径沿翼型外轮廓连续延伸
核心修复代码:
# 定位上下表面分界点(第一个尾缘点位置) split_idx = df[df[0] == 1.0].index[0] # 拆分上下表面坐标集 upper_surface = df.loc[:split_idx].copy() lower_surface = df.loc[split_idx+1:].copy() # 清理单段内的重复x坐标 upper_surface = upper_surface.drop_duplicates(subset=0, keep='first') lower_surface = lower_surface.drop_duplicates(subset=0, keep='first') # 拼接为符合绘图顺序的数据集 plot_df = pd.concat([upper_surface, lower_surface.iloc[::-1].iloc[1:]], axis=0) # 后续直接使用plot_df做插值、绘图即可,不会出现多余连线
内容的提问来源于stack exchange,提问作者John Chae
相关产品推荐
相关产品推荐

