You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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读取,按以下步骤调整:
    1. 先把网页里的纯文本数据提取出来,过滤掉所有HTML标签、开头的说明文字、空行,只保留带逗号分隔的有效数据行
    2. 修正列名列表的写法,每个列名单独作为列表的一个元素,不要把所有列名写在同一个字符串里,以下列名对应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'
]
  1. 注意区分两类数据行: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 01:54:33