傳送門
Python讀取dbf文件,轉化爲Pandas DataFrame
問題描述
- 在用python讀取一個dbf文件時發現有個字段不能正確解析,在調用DBF類的時候
table = DBF(r'D:\Projects\Repo 3\task_files\20191212\dbzqqyfaC17.dbf')
table.fields
發現其中一個 字段的 field 長度解析錯誤
DBFField(name='blfz2', type='N', address=179, length=17, decimal_count=12, reserved1=0, workarea_id=0, reserved2=0, reserved3=0, set_fields_flag=0, reserved4=b'\x00\x00\x00\x00\x00\x00\x00', index_field_flag=0)
DBFField(name='blfm2', type='C', address=196, length=3072, decimal_count=0, reserved1=0, workarea_id=0, reserved2=0, reserved3=0, set_fields_flag=0, reserved4=b'\x00\x00\x00\x00\x00\x00\x00', index_field_flag=0)
這樣導致接下來讀取 records 的時候,不能正常解析 數據。用excel 打開dbf文件發現 blfm2 其實是 float類型的數據,但是在dbf文件裏卻被 錯誤 定義成了 字符類型 ( ‘C’ type)
- 在查看了源代碼後發現問題出在了 dbf.py 裏 DBF 類的一個方法定義上,當遇到 ‘C’ (character) 類型的字段時,會去修改 field.length, field.decimal_count, 但這並不是我們想要的結果。
解決辦法
- 將源代碼裏的部分代碼註釋掉,如下所示,親測可行
def _read_field_headers(self, infile):
while True:
sep = infile.read(1)
if sep in (b'\r', b'\n', b''):
# End of field headers
break
field = DBFField.unpack(sep + infile.read(DBFField.size - 1))
field.type = chr(ord(field.type))
# 有些字段會出現定義錯誤,所以把這段註釋掉了
# For character fields > 255 bytes the high byte
# is stored in decimal_count.
# if field.type in 'C':
# field.length |= field.decimal_count << 8
# field.decimal_count = 0
# Field name is b'\0' terminated.
field.name = self._decode_text(field.name.split(b'\0')[0])
if self.lowernames:
field.name = field.name.lower()
self.field_names.append(field.name)
self.fields.append(field)