Pandas:将dbf表格转换为数据框架

25
我想读取ArcGIS shapefile的dbf文件并将其转储为pandas数据框。我目前正在使用dbf包。

我似乎已经能够将dbf文件加载为表格,但是一直没有找到如何解析它并将其转换为pandas数据框的方法。你有什么建议吗?

这就是我卡住的地方:

import dbf
thisTable = dbf.Table('C:\\Users\\myfolder\\project\\myfile.dbf')
thisTable.open(mode='read-only')

Python返回这个语句作为输出,我不知道该怎么理解:

dbf.ver_2.Table('C:\\Users\\myfolder\\project\\myfile.dbf', status='read-only')


编辑

我的原始dbf样本:

FID   Shape    E              N
0     Point    90089.518711   -201738.245555
1     Point    93961.324059   -200676.766517
2     Point    97836.321204   -199614.270439
...   ...      ...            ...

请问您能否提供一份原始的 .dbf 文件样本? - Fabio Lamanna
@FabioLamanna 请检查我的编辑。谢谢。 - FaCoffee
1
@CF84,你可能想阅读这篇文章 - MaxU - stand with Ukraine
@MaxU 非常非常有用,谢谢! - FaCoffee
3
@CF84,如果你需要处理DBF文件,你也可以采取以下方法:使用dbf模块读取.DBF文件,将其导出为CSV(.export()方法),然后在Pandas中解析此CSV。如果你的DBF文件不是很大,你可以使用io.StringIO缓冲区,而不是将CSV写入磁盘。 - MaxU - stand with Ukraine
你所看到的输出语句是由于 dbfopen() 上返回表格 -- 这是为了方便使用一行代码获取一个可用的表格:my_table = dbf.Table('somedata.dbf').open() - Ethan Furman
8个回答

56

你应该看一下simpledbf

In [2]: import pandas as pd

In [3]: from simpledbf import Dbf5

In [4]: dbf = Dbf5('test.dbf')

In [5]: df = dbf.to_dataframe()

这对我来说是有效的,使用一个小样本 .dbf 文件。


1
非常整洁的答案! - MaxU - stand with Ukraine
@FabioLamanna 为什么 FID 字段没有被读入到 df 中?实质上,我只看到了 EN 字段。如何确保所有字段都被读取? - FaCoffee
1
很好的答案,是否可以反过来做呢?也就是从 dataframe 转换为 dbf 文件? - DarkCygnus
1
@DarkCygnus,你解决了如何将数据框转换成dbf的问题了吗? - FaCoffee
使用Python 3进行开发。只需要执行“pip3 install simpledbf”即可。 - Rahal Kanishka
显示剩余2条评论

13

正如mmann1123所述,您可以使用geopandas来读取dbf文件。即使它可能没有地理空间数据,Geopandas也能读取它。

假设您的数据仅为表格数据(没有地理坐标),并且您希望将其读取并转换为pandas库可以读取的格式,则建议使用geopandas。

以下是一个示例:

import geopandas as gpd

My_file_path_name = r'C:\Users\...file_dbf.dbf'

Table = gpd.read_file(Filename)

import pandas as pd
Pandas_Table = pd.DataFrame(Table)

Keys = list(Table.keys())
Keys.remove('ID_1','ID_2') # removing ID attributes from the Table keys list
Keys.remove('Date') # eventually you have date attribute which you wanna preserve.

DS = pd.melt(Pandas_Table, 
             id_vars =['ID_1','ID_2'], # accepts multiple filter/ID values 
             var_name='class_fito', # Name of the variable which will aggregate all columns from the Table into the Dataframe
             value_name ='biomass (mg.L-1)' , # name of the variable in Dataframe
             value_vars= Keys # parameter that defines which attributes from the Table are a summary of the DataFrame)

# checking your DataFrame:

type(DS)   # should appear something like: pandas.core.frame.DataFrame

您无需加载pd.DataFrame(Table)来从Table获取数据帧... Table已经是一个Pandas数据帧。 - zelusp
1
这个很有效,但是 geopandas 会自动添加一个 geometry 列,这可能会在后面成为问题。对于不来自 shapefile 的 dbf 文件,你需要将其删除。gpd.read_file(filename).drop("geometry",axis=1) - rick debbout
只有当dbf文件附带其.shp文件时,它才对我有效。单个.dbf会导致IndexError(geopandas 0.6.1)。 - nantodevison
1
这是一个很好的答案;上面标记的那个在我的实现中将0值转换为NAN,我不知道geoapandas能够读取文件(使所有值保持一致)。谢谢。 - arbermejo

4

3
性能可能是一个问题。我测试了上述和其他一些库。在我的测试中,我使用了一个包含17列和23条记录(7 kb)的小型dbf文件。
simpledbf包有一个简单的方法to_dataframe()。而dbfread的DBF表对象的实际应用是可以通过将其作为参数添加到Python的内置函数iter()中来迭代它,其结果可以直接用于初始化dataframe。在pysal的情况下,我使用了函数dbf2DF,如此处所述。我使用上述方法将其他库的数据添加到dataframe中。但是,只有在检索字段名称以便首先用正确的列名初始化dataframe之后,才能完成此操作:分别从fieldNames,_meta.keys和ListFields函数中获取。
也许逐个添加记录并不是获取填充的dataframe最快的方式,这意味着当选择更聪明的方式将数据添加到dataframe时,使用dbfpy、dbf和arcpy进行测试会得出更有利的数字。无论如何,我希望以下时间(以秒为单位)表格有用:
simpledbf   0.0030
dbfread     0.0060
dbfpy       0.0140
pysal       0.0160
dbf         0.0210
arcpy       2.7770

2
这对我有用:

这个方法适用于我:

import geopandas as gpd

df = gpd.read_file('some_file.dbf').drop("geometry",axis=1)

2
使用 dbfpy 如何?这里有一个例子,展示如何将具有 3 列的 dbf 文件加载到数据框中:
from dbfpy import dbf
import pandas as pd

df = pd.DataFrame(columns=('tileno', 'grid_code', 'area'))
db = dbf.Dbf('test.dbf')
for rec in db:
    data = []
    for i in range(len(rec.fieldData)):
        data.append(rec[i])
    df.loc[len(df.index)] = data
db.close()

如果需要的话,您可以从db.fieldNames中找到列名。

2

如何将DBF文件的内容加载到Pandas数据框中。

Pandas无法检测到DBF对象是可迭代的,因此需要使用iter()方法。

#import
from dbfread import DBF
import pandas as pd


dbf = DBF('people.dbf')
dataResult = pd.DataFrame(iter(dbf))

print(dataResult)

1
我使用了在PyPi上找到的版本为0.99.1的'dbf',它工作得非常好。
import dbf
import pandas as pd

table = dbf.Table(filename=filepath)
table.open(dbf.READ_ONLY)
df = pd.DataFrame(table)
table.close()

print(df)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接