将DBC文件转换为CSV时遇浮点数转换错误的技术问询
DBC转CSV浮点数转换错误问题解决
问题背景
使用R的read.dbc处理巴西Datasus卫生数据(25个州15年每月一份,单文件50万行10列)时速度极慢,单文件需5分钟,总计耗时约1个月,计划转为CSV提升效率。在Windows系统尝试多种转换方案:
- danicat的方案依赖Linux环境,无法直接在Windows使用;
- 使用greatjapa基于
simpledbf的方案时,加载文件成功但转换CSV出现浮点数转换错误,错误栈如下:
>>> from dbfread import DBF >>> dbc_file = "RDAC0901.dbc" >>> csv_file = "RDAC0901.csv" >>> dbf = Dbf5(dbc_file, codec='ISO-8859-1') >>> dbf.to_csv(csv_file) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Users\calebep\AppData\Roaming\Python\Python312\site-packages\simpledbf\simpledbf.py", line 172, in to_csv for n, result in enumerate(self._get_recs()): File "C:\Users\calebep\AppData\Roaming\Python\Python312\site-packages\simpledbf\simpledbf.py", line 612, in _get_recs value = float(value) ^^^^^^^^^^^^
测试文件可通过curl -O ftp://ftp.datasus.gov.br/dissemin/publicos/SIHSUS/200801_/Dados/RDAC0901.dbc获取。
错误原因
错误源于simpledbf库强制将字段值转换为float时失败,核心原因有两个:
- 数值字段存在非数值内容:Datasus部分数据中,数值型字段的缺失值可能用空格、空字符串或特殊符号填充,这些内容无法直接转为浮点数;
- 字段类型识别错误:
simpledbf可能误将字符型字段判定为数值型,而该字段实际包含无法转换为浮点数的字符串内容。
解决方案
方案1:修改simpledbf的转换逻辑,处理异常
找到simpledbf.py(路径:C:\Users\calebep\AppData\Roaming\Python\Python312\site-packages\simpledbf\simpledbf.py)第612行附近的代码:
value = float(value)
替换为带异常捕获的逻辑,处理无法转换的情况:
import pandas as pd # 需提前安装pandas try: # 先去除首尾空格,空值转为pd.NA cleaned_value = value.strip() value = float(cleaned_value) if cleaned_value else pd.NA except ValueError: # 转换失败时保留原始值或设为缺失值 value = pd.NA
修改后重新运行转换代码,即可跳过或处理异常值。
方案2:使用Datasus专用Python库dbcreader
dbcreader是专门为Datasus的DBC文件开发的库,对字段类型和缺失值处理更适配:
- 安装库:
pip install dbcreader
- 转换代码:
from dbcreader import read_dbc import pandas as pd dbc_file = "RDAC0901.dbc" csv_file = "RDAC0901.csv" # 读取DBC为DataFrame df = read_dbc(dbc_file, encoding='ISO-8859-1') # 导出为CSV df.to_csv(csv_file, index=False, encoding='ISO-8859-1')
该库能自动处理Datasus数据的特殊格式,避免转换错误。
方案3:Windows上用WSL运行danicat的dbc2dbf工具
danicat的工具对Datasus DBC支持最完善,可通过WSL在Windows上运行:
- 启用WSL并安装Ubuntu发行版;
- 在WSL终端安装依赖:
sudo apt-get install liblzma-dev
- 下载
dbc2dbf源码,解压后编译:
cd dbc2dbf make
- 执行转换(先转DBF再转CSV):
./dbc2dbf RDAC0901.dbc RDAC0901.dbf # 用pandas读取DBF并导出CSV python -c "import pandas as pd; df=pd.read_dbf('RDAC0901.dbf', encoding='ISO-8859-1'); df.to_csv('RDAC0901.csv', index=False)"
这种方式适合批量处理,速度快且兼容性强。
批量处理优化建议
针对大量文件的场景,可进一步优化:
- 使用多进程/多线程:用Python的
concurrent.futures模块并行转换多个文件,大幅减少总耗时; - 预处理抽样:先抽取少量文件分析字段异常情况,统一处理逻辑后再批量执行。
内容的提问来源于stack exchange,提问作者Calebe Piacentini
相关产品推荐
相关产品推荐

