在 python 中将 dbf 转换为 csv 的方法?
Way to convert dbf to csv in python?
我有一个包含一堆 dbf 文件的文件夹,我想将其转换为 csv。我曾尝试使用代码将扩展名从 .dbf 更改为 .csv,当我使用 Excel 时这些文件可以正常打开,但是当我在 pandas 中打开它们时它们看起来像这样:
s\t�
0 NaN
1 1 176 1.58400000000e+005-3.385...
这不是我想要的,那些字符不会出现在真实文件中。
我应该如何正确读取dbf文件?
上网查了一下,有几种选择:
- https://gist.github.com/ryanhill29/f90b1c68f60d12baea81
- http://pandaproject.net/docs/importing-dbf-files.html
- https://geodacenter.asu.edu/blog/2012/01/17/dbf-files-and-p
- https://pypi.python.org/pypi/simpledbf
dbf = Dbf5('fake_file_name.dbf')
df = dbf.to_dataframe()
根据要点进行调整:
import pysal as ps
def dbf2DF(dbfile, upper=True):
"Read dbf file and return pandas DataFrame"
with ps.open(dbfile) as db: # I suspect just using open will work too
df = pd.DataFrame({col: db.by_col(col) for col in db.header})
if upper == True:
df.columns = map(str.upper, db.header)
return df
编辑#2:
可以逐行读取 dbf 文件,无需转换为 csv,使用 dbfread
(只需使用 pip install dbfread
安装):
>>> from dbfread import DBF
>>> for row in DBF('southamerica_adm0.dbf'):
... print row
...
OrderedDict([(u'COUNTRY', u'ARGENTINA')])
OrderedDict([(u'COUNTRY', u'BOLIVIA')])
OrderedDict([(u'COUNTRY', u'BRASIL')])
OrderedDict([(u'COUNTRY', u'CHILE')])
OrderedDict([(u'COUNTRY', u'COLOMBIA')])
OrderedDict([(u'COUNTRY', u'ECUADOR')])
OrderedDict([(u'COUNTRY', u'GUYANA')])
OrderedDict([(u'COUNTRY', u'GUYANE')])
OrderedDict([(u'COUNTRY', u'PARAGUAY')])
OrderedDict([(u'COUNTRY', u'PERU')])
OrderedDict([(u'COUNTRY', u'SURINAME')])
OrderedDict([(u'COUNTRY', u'U.K.')])
OrderedDict([(u'COUNTRY', u'URUGUAY')])
OrderedDict([(u'COUNTRY', u'VENEZUELA')])
我更新的参考资料:
官方项目网站:http://pandas.pydata.org
官方文档:http://pandas-docs.github.io/pandas-docs-travis/
dbfread
: https://pypi.python.org/pypi/dbfread/2.0.6
geopandas
: http://geopandas.org/
shp and dbf with geopandas
: https://gis.stackexchange.com/questions/129414/only-read-specific-attribute-columns-of-a-shapefile-with-geopandas-fiona
使用 my dbf library 你可以这样做:
import sys
import dbf
for arg in sys.argv[1:]:
dbf.export(arg)
这将创建一个与每个 dbf 文件同名的 .csv
文件。如果将该代码放入名为 dbf2csv.py
的脚本中,则可以将其命名为
python dbf2csv.py dbfname dbf2name dbf3name ...
这是我多年来一直使用的解决方案。我有一个 Python 2.7 的解决方案和一个 Python 3.5(可能还有 3.6)的解决方案。
Python 2.7:
import csv
from dbfpy import dbf
def dbf_to_csv(out_table):#Input a dbf, output a csv
csv_fn = out_table[:-4]+ ".csv" #Set the table as .csv format
with open(csv_fn,'wb') as csvfile: #Create a csv file and write contents from dbf
in_db = dbf.Dbf(out_table)
out_csv = csv.writer(csvfile)
names = []
for field in in_db.header.fields: #Write headers
names.append(field.name)
out_csv.writerow(names)
for rec in in_db: #Write records
out_csv.writerow(rec.fieldData)
in_db.close()
return csv_fn
Python 3.5:
import csv
from dbfread import DBF
def dbf_to_csv(dbf_table_pth):#Input a dbf, output a csv, same name, same path, except extension
csv_fn = dbf_table_pth[:-4]+ ".csv" #Set the csv file name
table = DBF(dbf_table_pth)# table variable is a DBF object
with open(csv_fn, 'w', newline = '') as f:# create a csv file, fill it with dbf content
writer = csv.writer(f)
writer.writerow(table.field_names)# write the column name
for record in table:# write the rows
writer.writerow(list(record.values()))
return csv_fn# return the csv name
您可以从 pip 安装中获取 dbfpy 和 dbfread。
首先你应该知道你有什么版本的 Dbf,所以请阅读文件的第一个字节:
path = "/path/to/dbf/file.dbf"
with open(path, "rb") as f:
byte = f.read(1)
print(f"You have a DBF {int.from_bytes(byte)} file.")
示例:
> 您有一个 DBF 3 文件。
如果你有一个 Dbf 5 文件,一切都会好起来的,但是如果你有一个 Dbf 3 文件,大多数情况下我就是这种情况,你必须使用 simpledbf 调整 :
在this问题之后,基本上你应该创建一个继承Dbf5的class Dbf3,但是你需要在_get_recs[=中添加一个新的条件32=]方法。
import struct
from simpledbf import Dbf5
class Dbf3(Dbf5):
def __init__(self, dbf, codec='utf-8'):
super().__init__(dbf, codec)
def _get_recs(self, chunk=None):
#[...copy the code from the original class up until line 664...]
elif typ == 'M':
value = self._na
#[...copy the code from the original class after 664...]
Original Dbf code for reference
那么您的新 class Dbf3 将能够轻松读取和转换 Dbf3 文件:
dbf = Dbf3(filename, codec="iso-8859-1") #codec specific to this dataset
dbf.to_csv("converted_dbf.csv")
我有一个包含一堆 dbf 文件的文件夹,我想将其转换为 csv。我曾尝试使用代码将扩展名从 .dbf 更改为 .csv,当我使用 Excel 时这些文件可以正常打开,但是当我在 pandas 中打开它们时它们看起来像这样:
s\t�
0 NaN
1 1 176 1.58400000000e+005-3.385...
这不是我想要的,那些字符不会出现在真实文件中。
我应该如何正确读取dbf文件?
上网查了一下,有几种选择:
- https://gist.github.com/ryanhill29/f90b1c68f60d12baea81
- http://pandaproject.net/docs/importing-dbf-files.html
- https://geodacenter.asu.edu/blog/2012/01/17/dbf-files-and-p
- https://pypi.python.org/pypi/simpledbf
dbf = Dbf5('fake_file_name.dbf')
df = dbf.to_dataframe()
根据要点进行调整:
import pysal as ps
def dbf2DF(dbfile, upper=True):
"Read dbf file and return pandas DataFrame"
with ps.open(dbfile) as db: # I suspect just using open will work too
df = pd.DataFrame({col: db.by_col(col) for col in db.header})
if upper == True:
df.columns = map(str.upper, db.header)
return df
编辑#2:
可以逐行读取 dbf 文件,无需转换为 csv,使用 dbfread
(只需使用 pip install dbfread
安装):
>>> from dbfread import DBF
>>> for row in DBF('southamerica_adm0.dbf'):
... print row
...
OrderedDict([(u'COUNTRY', u'ARGENTINA')])
OrderedDict([(u'COUNTRY', u'BOLIVIA')])
OrderedDict([(u'COUNTRY', u'BRASIL')])
OrderedDict([(u'COUNTRY', u'CHILE')])
OrderedDict([(u'COUNTRY', u'COLOMBIA')])
OrderedDict([(u'COUNTRY', u'ECUADOR')])
OrderedDict([(u'COUNTRY', u'GUYANA')])
OrderedDict([(u'COUNTRY', u'GUYANE')])
OrderedDict([(u'COUNTRY', u'PARAGUAY')])
OrderedDict([(u'COUNTRY', u'PERU')])
OrderedDict([(u'COUNTRY', u'SURINAME')])
OrderedDict([(u'COUNTRY', u'U.K.')])
OrderedDict([(u'COUNTRY', u'URUGUAY')])
OrderedDict([(u'COUNTRY', u'VENEZUELA')])
我更新的参考资料:
官方项目网站:http://pandas.pydata.org
官方文档:http://pandas-docs.github.io/pandas-docs-travis/
dbfread
: https://pypi.python.org/pypi/dbfread/2.0.6
geopandas
: http://geopandas.org/
shp and dbf with geopandas
: https://gis.stackexchange.com/questions/129414/only-read-specific-attribute-columns-of-a-shapefile-with-geopandas-fiona
使用 my dbf library 你可以这样做:
import sys
import dbf
for arg in sys.argv[1:]:
dbf.export(arg)
这将创建一个与每个 dbf 文件同名的 .csv
文件。如果将该代码放入名为 dbf2csv.py
的脚本中,则可以将其命名为
python dbf2csv.py dbfname dbf2name dbf3name ...
这是我多年来一直使用的解决方案。我有一个 Python 2.7 的解决方案和一个 Python 3.5(可能还有 3.6)的解决方案。
Python 2.7:
import csv
from dbfpy import dbf
def dbf_to_csv(out_table):#Input a dbf, output a csv
csv_fn = out_table[:-4]+ ".csv" #Set the table as .csv format
with open(csv_fn,'wb') as csvfile: #Create a csv file and write contents from dbf
in_db = dbf.Dbf(out_table)
out_csv = csv.writer(csvfile)
names = []
for field in in_db.header.fields: #Write headers
names.append(field.name)
out_csv.writerow(names)
for rec in in_db: #Write records
out_csv.writerow(rec.fieldData)
in_db.close()
return csv_fn
Python 3.5:
import csv
from dbfread import DBF
def dbf_to_csv(dbf_table_pth):#Input a dbf, output a csv, same name, same path, except extension
csv_fn = dbf_table_pth[:-4]+ ".csv" #Set the csv file name
table = DBF(dbf_table_pth)# table variable is a DBF object
with open(csv_fn, 'w', newline = '') as f:# create a csv file, fill it with dbf content
writer = csv.writer(f)
writer.writerow(table.field_names)# write the column name
for record in table:# write the rows
writer.writerow(list(record.values()))
return csv_fn# return the csv name
您可以从 pip 安装中获取 dbfpy 和 dbfread。
首先你应该知道你有什么版本的 Dbf,所以请阅读文件的第一个字节:
path = "/path/to/dbf/file.dbf"
with open(path, "rb") as f:
byte = f.read(1)
print(f"You have a DBF {int.from_bytes(byte)} file.")
示例:
> 您有一个 DBF 3 文件。
如果你有一个 Dbf 5 文件,一切都会好起来的,但是如果你有一个 Dbf 3 文件,大多数情况下我就是这种情况,你必须使用 simpledbf 调整
在this问题之后,基本上你应该创建一个继承Dbf5的class Dbf3,但是你需要在_get_recs[=中添加一个新的条件32=]方法。
import struct
from simpledbf import Dbf5
class Dbf3(Dbf5):
def __init__(self, dbf, codec='utf-8'):
super().__init__(dbf, codec)
def _get_recs(self, chunk=None):
#[...copy the code from the original class up until line 664...]
elif typ == 'M':
value = self._na
#[...copy the code from the original class after 664...]
Original Dbf code for reference
那么您的新 class Dbf3 将能够轻松读取和转换 Dbf3 文件:
dbf = Dbf3(filename, codec="iso-8859-1") #codec specific to this dataset
dbf.to_csv("converted_dbf.csv")