[ValueError: could not convert string to float 오류] Python으로 DBF 파일 dataframe으로 열기

JeongYun Lee·2024년 4월 23일

Others

목록 보기
3/7

dbf_qgis

DBF파일을 처음 봤는데, QGIS로는 쉽게 열렸지만 python으로 열기 쉽지 않았다. 구글링해보면 simpledbfdbfread를 사용하라고 해서 처음에는 그렇게 접근했다. 두 방법 모두 같은 에러가 나왔고, 해결하진 못했다. 데이터의 문제인 것 같기도 해서 (다른 데이터로는 성공했었다고 함) 일단 코드를 공유한다.

방법1

pip install simpledbf
# simple dbf
from simpledbf import Dbf5
import pandas as pd

dbf = Dbf5('data.dbf', codec='utf-8')
df = dbf.to_dataframe()

방법2

pip instll dbfread
from dbfread import DBF
import pandas as pd

table = DBF('data.dbf', load=True) 
df = pd.DataFrame(table.records)

오류코드

ValueError: could not convert string to float: b'151549.64526568\x00\x00'

codec을 utf-8, euc-kr, cp949 바꿔가면서 해봤지만 모두 동일한 에러가 발생했다. 나중에 데이터를 열어서 확인해보니 바이트 문자열 (enter)이 들어있어서 float으로 변환할 수 없다는 의미였다. 관련 내용을 구글링해봐도 dbf 파일을 열 때 해당 에러를 해결했다는 글을 찾아보기 어려웠다.

해결방법

import dbf

# Define the function to fix float conversion
def fix_float(string):
    try:
        return float(string)
    except ValueError:
        return 0.0

data = dbf.Table('data.dbf', default_data_types={'N': fix_float})
data.open()

위 코드는 이 stackoverflow 글에서 가져왔고, 이를 활용해서 data라는 변수에 데이터를 쭉 담아주고 dataframe으로 다시 변환하기로 했다. data의 type은 dbf.tables.Db3Table이라서 바로 dataframe에 넣어주진 못했고, 리스트 형식으로 들어가 있어서 for 문으로 한 행씩 데이터를 담아서 이중리스트를 만든 뒤 dataframe에 넣어줬다. 아래 코드를 보면 이해될 것이다.

total_list = []

for i in tqdm(range(len(data))):
    row_list = []
    for j in data[i]:
        row_list.append(str(j))
    total_list.append(row_list)
    
columns = ['col1', 'col2', 'col3', 'col4', 'col5']

# 데이터프레임으로 변환
df = pd.DataFrame(total_list, columns=columns)
df

이중 for문을 돌려야 해서 굉장히 비효율적이고 데이터 양이 많으면 오랜 시간이 걸리겠지만... 지금으로썬 이 방법이 최선이었다.

추가에러

처음에 연 파일은 위 방법으로 잘 해결했는데, 두 번째 파일은 다시 말썽이었다. data로 넣어준 것 까지는 괜찮았는데 list에 담아주는 과정에서 UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 1: ordinal not in range(128) 에러가 발생했다. QGIS로 데이터를 열어보니 디코딩되지 않은 한 행이 존재하는 것을 확인할 수 있었다.

휴~ 해결하면 다시 추가하겠다...

profile
궁금한 건 많지만, 천천히 알아가는 중입니다

0개의 댓글