web-dev-qa-db-fra.com

Pandas: transformer une table dbf en une trame de données

Je souhaite lire un fichier dbf d'un fichier de formes ArcGIS et le vider dans un cadre de données pandas. J'utilise actuellement le package dbf .

J'ai apparemment été en mesure de charger le fichier dbf en tant que tableau, mais je n'ai pas réussi à comprendre comment l'analyser et le transformer en un pandas dataframe. Quelle est la façon de procéder?

C'est là que je suis coincé:

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

Python renvoie cette déclaration en sortie, dont je ne sais franchement pas quoi faire:

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


ÉDITER

Échantillon de mon dbf d'origine:

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

Vous devriez jeter un œil à 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()

Cela fonctionne pour moi avec un petit exemple de fichier .dbf. J'espère que cela pourra aider.

24
Fabio Lamanna

Comme l'a indiqué mmann1123, vous pouvez utiliser des géopandas pour lire votre fichier dbf. Le Geopandas le lit même s'il peut ou non avoir des données géospatiales.

En supposant que vos données ne sont que des données tabulaires (pas de coordonnées géographiques), et que vous souhaitez les lire et les convertir dans un format que pandas peut lire, je suggère d'utiliser des géopandas.

Voici un exemple:

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
6

Vous voudrez peut-être regarder les géopandas. Il vous permettra d'effectuer les opérations SIG les plus importantes

http://geopandas.org/data_structures.html

4
mmann1123

Que diriez-vous d'utiliser dbfpy ? Voici un exemple qui montre comment charger un dbf avec 3 colonnes dans une trame de données:

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()

Si nécessaire, vous pouvez trouver les noms des colonnes dans db.fieldNames.

2
Dobedani

Les performances peuvent être un problème. J'ai testé quelques-unes des bibliothèques suggérées ci-dessus et ailleurs. Pour mon test, j'ai utilisé un petit fichier dbf de 17 colonnes et 23 enregistrements (7 ko).

Le paquet simpledbf a une méthode simple to_dataframe (). Et l'aspect pratique de l'objet table DBF de dbfread est la possibilité de simplement le parcourir en l'ajoutant comme argument à la fonction intégrée de Python iter (), dont le résultat peut être utilisé pour initialiser directement une trame de données. Dans le cas de pysal, j'ai utilisé la fonction dbf2DF comme décrit ici . Les données des autres bibliothèques que j'ai ajoutées à la trame de données en utilisant la méthode indiquée ci-dessus. Cependant, seulement après avoir récupéré les noms de champ afin que je puisse d'abord initialiser le cadre de données avec les noms de colonne de droite: à partir des champs FieldNames, _meta.keys et au moyen de la fonction ListFields respectivement.

L'ajout d'enregistrements 1 par 1 n'est probablement pas le moyen le plus rapide d'obtenir une trame de données remplie, ce qui signifie que les tests avec dbfpy, dbf et arcpy donneraient des chiffres plus favorables lorsqu'une façon plus intelligente serait choisie pour ajouter les données à la trame de données. J'espère tout de même que le tableau suivant - avec des temps en secondes - est utile:

simpledbf   0.0030
dbfread     0.0060
dbfpy       0.0140
pysal       0.0160
dbf         0.0210
arcpy       2.7770
2
Dobedani