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

如何将在线TXT文件转换为pandas DataFrame并定义列名追加数据

问题原因

原代码存在4个核心错误,导致无法正常读取txt并合并DataFrame:

  • pd.read_csv() 不支持直接传入纯文本字符串输入,该方法仅接受本地文件路径或带read方法的类文件对象,直接传入requests返回的text字符串会被识别为无效本地路径,触发文件不存在报错。
  • pandas的DataFrame.append()不会原地修改原对象,每次调用会返回全新的拼接后DataFrame,原写法未接收返回值,所有拼接操作都不会生效。
  • 初始化DataFrame时漏写pandas前缀,直接调用DataFrame()会触发名称错误。
  • 人口普查局该目录下的txt文件前4行是调查说明、统计口径等元数据,不是正式结构化数据,直接读取会把说明文字识别为数据行,导致格式完全错乱。
修正方案
  1. 用标准库io.StringIO把requests返回的文本内容包装为类文件对象,再传给pandas读取。
  2. 放弃循环逐次append的写法,用列表暂存每个txt生成的临时DataFrame,最后用pd.concat()一次性合并,性能更高。
  3. 读取时通过skiprows参数跳过开头的非数据行,可提前自定义列名传入,也可指定文件自带表头的位置直接使用。
  4. 这批早期普查文件默认用latin-1编码,解码时指定编码避免乱码。

修正后的可运行代码:

from bs4 import BeautifulSoup
import pandas as pd
import requests
import io
from bs4.dammit import EncodingDetector 

target_url = 'https://www2.census.gov/econ/bps/Place/West%20Region/'
parser = 'html.parser'
page_resp = requests.get(target_url)
http_encoding = page_resp.encoding if 'charset' in page_resp.headers.get('content-type', '').lower() else None
html_encoding = EncodingDetector.find_declared_encoding(page_resp.content, is_html=True)
page_encoding = html_encoding or http_encoding
region_soup = BeautifulSoup(page_resp.content, parser, from_encoding=page_encoding)

# 按文件字段顺序自定义列名,不需要自定义可删除相关配置,直接使用文件自带表头
custom_cols = [
    "fips_code", "place_name", "total_permit_units", "single_family_units",
    "two_unit_units", "three_four_unit_units", "five_plus_unit_units"
]

df_container = []
for link in region_soup.find_all('a', href=True):
    file_name = link['href']
    if not file_name.endswith(".txt"):
        continue
    print(f"处理文件: {file_name}")
    file_resp = requests.get(target_url + file_name)
    # 用latin-1解码老普查文件避免乱码
    file_text = file_resp.content.decode('latin-1')
    file_buffer = io.StringIO(file_text)
    
    # 读取配置可根据实际文件格式调整
    temp_df = pd.read_csv(
        file_buffer,
        sep=",",  # 如果是空白分隔文件替换为r'\s+',固定宽度文件换用pd.read_fwf
        skiprows=4,  # 跳过前4行元数据说明,根据实际文件格式调整行数
        skip_blank_lines=True,
        names=custom_cols,  # 用自定义列名,使用文件自带表头请删除本行
        header=None  # 配合自定义列名跳过文件自带表头行,使用文件自带表头请删除本行并设置header=表头行索引
    )
    # 新增来源字段方便后续数据溯源
    temp_df["source_file"] = file_name
    df_container.append(temp_df)

# 一次性合并所有数据
final_df = pd.concat(df_container, ignore_index=True)
配置说明
  • 列名定义:如果不需要自定义列,删除names=custom_cols和header=None两个参数,将header设置为文件中表头所在的行索引即可(行索引从0开始计数,比如表头在第5行就设置header=4)。
  • 格式适配:如果读取时出现列错位,手动打开1-2个目标txt文件,确认分隔符类型、开头非数据行数量,对应调整sep和skiprows参数即可。部分年份的早期文件是固定宽度格式,把pd.read_csv替换为pd.read_fwf即可,其余参数逻辑一致。
  • 数据清洗:合并完成后可按需做数据类型转换、空值过滤、字段拆分等后续处理。

内容的提问来源于stack exchange,提问作者matt stoebe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:33:19