2 votes

Comment ignorer les données inutiles lors de l'extraction de données d'un fichier texte vers pandas ?

Tengo url qui contient un fichier texte que je veux charger dans le dataframe de pandas. Mais il y a des métadonnées en haut du fichier que je ne peux pas ignorer lors de l'analyse et qui renvoie une erreur.

ParserError: Error tokenizing data. C error: Expected 1 fields in line 3, saw 2

Voici le code que j'ai :

import pandas as pd
data = pd.read_csv('https://fred.stlouisfed.org/data/PERMIT.txt')

Ce code fonctionne généralement pour moi lorsqu'il n'y a pas de métadonnées en haut. Comment puis-je ignorer les métadonnées lors du chargement ?

Le début de la txt ressemble à un fichier :

Title:               New Private Housing Units Authorized by Building Permits
Series ID:           PERMIT
Source:              U.S. Bureau of the Census, U.S. Department of Housing and Urban Development
Release:             New Residential Construction
Seasonal Adjustment: Seasonally Adjusted Annual Rate
Frequency:           Monthly
Units:               Thousands of Units
Date Range:          1960-01-01 to 2018-03-01
Last Updated:        2018-04-24 7:01 AM CDT
Notes:               Starting with the 2005-02-16 release, the series reflects an increase
                     in the universe of permit-issuing places from 19,000 to 20,000 places.

DATE        VALUE
1960-01-01   1092
1960-02-01   1088
1960-03-01    955
1960-04-01   1016
1960-05-01   1052
1960-06-01    958
1960-07-01    999
1960-08-01    994

4voto

sacul Points 29881

Utilisez le skiprows pour ignorer vos métadonnées. Dans votre cas, vous avez 12 lignes :

data = pd.read_csv('https://fred.stlouisfed.org/data/PERMIT.txt', skiprows=12, sep='\s+')
>>> data.head()
   DATE        VALUE
0  1960-01-01   1092
1  1960-02-01   1088
2  1960-03-01    955
3  1960-04-01   1016
4  1960-05-01   1052

Alternativement, dites read_csv où l'en-tête est avec le header (ligne 11) :

data = pd.read_csv('https://fred.stlouisfed.org/data/PERMIT.txt', header=11, sep='\s+')
>>> data.head()
   DATE        VALUE
0  1960-01-01   1092
1  1960-02-01   1088
2  1960-03-01    955
3  1960-04-01   1016
4  1960-05-01   1052

Si vous ne savez pas combien de lignes il faut sauter, vous pouvez mettre en œuvre la stratégie utilisée dans le document suivant cette réponse

2voto

piRSquared Points 159

Si vous vouliez préserver l'en-tête :

import pandas as pd
from pandas.io.common import StringIO as sio
import requests as req

url = 'https://fred.stlouisfed.org/data/PERMIT.txt'
res = req.request('get', url).content.decode()

h, b = res.replace('\r', '').split('\n\n')

s = pd.read_fwf(
    sio(h.replace(':', '')),
    header=None,
    names=['key', 'value']
).ffill().groupby('key').value.apply('\n'.join)

df = pd.read_csv(sio(b), delim_whitespace=True)

Alors, voyez nos travaux pratiques

print(s.head(), df.head(), sep='\n\n')

key
Date Range                               1960-01-01 to 2018-03-01
Frequency                                                 Monthly
Last Updated                                2018-04-24 701 AM CDT
Notes           Starting with the 2005-02-16 release, the seri...
Release                              New Residential Construction
Name: value, dtype: object

         DATE  VALUE
0  1960-01-01   1092
1  1960-02-01   1088
2  1960-03-01    955
3  1960-04-01   1016
4  1960-05-01   1052

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X