
DBF파일을 처음 봤는데, QGIS로는 쉽게 열렸지만 python으로 열기 쉽지 않았다. 구글링해보면 simpledbf나 dbfread를 사용하라고 해서 처음에는 그렇게 접근했다. 두 방법 모두 같은 에러가 나왔고, 해결하진 못했다. 데이터의 문제인 것 같기도 해서 (다른 데이터로는 성공했었다고 함) 일단 코드를 공유한다.
pip install simpledbf
# simple dbf
from simpledbf import Dbf5
import pandas as pd
dbf = Dbf5('data.dbf', codec='utf-8')
df = dbf.to_dataframe()
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로 데이터를 열어보니 디코딩되지 않은 한 행이 존재하는 것을 확인할 수 있었다.
휴~ 해결하면 다시 추가하겠다...