Python运行pd.read_csv报Too many columns specified错误如何解决
错误原因
- 核心触发点:你传入
pd.read_csv的目标地址返回的不是纯CSV格式文件,是带完整HTML标签的网页。网页头部的说明文字、HTML标签行都没有逗号分隔符,整行内容会被识别为1个字段,当pandas读取到后续逗号分隔的20列真实气象数据行时,就会触发列数不匹配报错。 - 列名定义存在写法问题:你示例代码里写的
columnnames= ['a,b,c,etc']是长度为1的列表(所有列名被塞在了同一个字符串里),实际运行时你应该是替换成了包含20个真实列名的列表,此时pandas会默认所有行都应该匹配20个列的长度,一旦碰到只有1个字段的非数据行,就会抛出你看到的Too many columns specified: expected 20 and found 1错误。 - 逻辑冗余:你代码开头已经调用了专门解析HURDAT2数据的
readHURDAT2(url)函数,该函数本身就是为了处理这个数据源的非标准格式编写的,你后续跳过该函数的返回结果,直接用通用的pd.read_csv读取原始URL,等于完全没用到现成的解析逻辑。
修复方案
- 优先方案:直接复用
readHURDAT2的返回结果,不要重复读取原始URL。该函数已经处理了网页内容提取、头部行/数据行区分、格式解析的逻辑,你只需要把返回的结构化数据转成需要的格式即可,不需要再自己实现读取逻辑。 - 如果要手动用pandas读取,按以下步骤调整:
- 先把网页里的纯文本数据提取出来,过滤掉所有HTML标签、开头的说明文字、空行,只保留带逗号分隔的有效数据行
- 修正列名列表的写法,每个列名单独作为列表的一个元素,不要把所有列名写在同一个字符串里,以下列名对应HURDAT2的20个常规观测字段:
columnnames = [ 'date', 'time', 'record_identifier', 'system_status', 'latitude', 'longitude', 'max_sustained_wind', 'min_pressure', 'ne_34kt_radius', 'se_34kt_radius', 'sw_34kt_radius', 'nw_34kt_radius', 'ne_50kt_radius', 'se_50kt_radius', 'sw_50kt_radius', 'nw_50kt_radius', 'ne_64kt_radius', 'se_64kt_radius', 'sw_64kt_radius', 'nw_64kt_radius' ]
- 注意区分两类数据行:HURDAT2里每段风暴的头部行只有3个字段(风暴编号、风暴名称、观测记录条数),后续的观测行才是20个字段,不能直接用统一的20列配置读取所有行,需要先逐行判断行的字段数,分别处理。
参考实现代码:
import requests import pandas as pd from bs4 import BeautifulSoup url = 'https://www.aoml.noaa.gov/hrd/hurdat/hurdat2.html' # 拉取网页并提取纯文本 resp = requests.get(url, timeout=10) soup = BeautifulSoup(resp.text, 'html.parser') raw_text = soup.get_text() # 过滤有效行 valid_lines = [] for line in raw_text.splitlines(): stripped = line.strip() if stripped and ',' in stripped: valid_lines.append(stripped) # 区分风暴头行和观测行分别处理 storm_records = [] observation_records = [] for line in valid_lines: fields = [f.strip() for f in line.split(',') if f.strip()] if len(fields) == 3: # 风暴头行 storm_records.append(fields) elif len(fields) == 20: # 观测行 observation_records.append(fields) # 转成DataFrame storm_df = pd.DataFrame(storm_records, columns=['storm_id', 'storm_name', 'record_count']) obs_df = pd.DataFrame(observation_records, columns=columnnames)
内容的提问来源于stack exchange,提问作者help_me
相关产品推荐
相关产品推荐

