Panda read_csv dall'URL


139

Sto usando Python 3.4 con IPython e ho il seguente codice. Non riesco a leggere un file CSV dall'URL indicato:

import pandas as pd
import requests

url="https://github.com/cs109/2014_data/blob/master/countries.csv"
s=requests.get(url).content
c=pd.read_csv(s)

Ho il seguente errore

"Nome percorso del file o oggetto simile al file previsto, tipo ottenuto"

Come posso risolvere questo problema?


Avresti bisogno di qualcosa di simile, c=pd.read_csv(io.StringIO(s.decode("utf-8")))ma stai ricevendo HTML non un file CSV, quindi non funzionerà
Padraic Cunningham

3
Sono abbastanza sicuro che l'URL che desideri sia "https://raw.github.com/cs109/2014_data/blob/master/countries.csv".
kylie.a,

@venom, ha scelto la risposta più popolare come quella giusta
ibodi,

Risposte:


167

Aggiornare

Dai panda 0.19.2ora puoi semplicemente passare direttamente l'URL .


Proprio come suggerisce l'errore, è pandas.read_csvnecessario un oggetto simile a un file come primo argomento.

Se vuoi leggere il CSV da una stringa, puoi usare io.StringIO(Python 3.x) o StringIO.StringIO(Python 2.x) .

Inoltre, per l'URL - https://github.com/cs109/2014_data/blob/master/countries.csv - stai ricevendo una htmlrisposta, non un csv grezzo, dovresti usare l'URL fornito dal Rawlink nella pagina di github per ottenere una risposta csv grezza, che è - https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv

Esempio -

import pandas as pd
import io
import requests
url="https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv"
s=requests.get(url).content
c=pd.read_csv(io.StringIO(s.decode('utf-8')))

Che cosa succede se la risposta è grande e voglio trasmetterla in streaming invece di consumare memoria per il contenuto codificato, il contenuto decodificato e l'oggetto StringIO?
Akaihola,

9
Nell'ultima versione di Panda puoi dare l'URL direttamente, cioèc=pd.read_csv(url)
inodb,

Curiosamente ho una versione più recente di pandas(0.23.4), ma non ho potuto dare l'url direttamente. Questa risposta mi ha aiutato a farlo funzionare.
Antti,

1
"Aggiorna da Panda 0.19.2 ora puoi semplicemente passare direttamente l'URL." A meno che non sia possibile perché è necessario passare argomenti di autenticazione, nel qual caso l'esempio originale è molto necessario.
Aaron Hall

Questa soluzione è ancora utile se hai bisogno di una migliore gestione degli errori usando i codici HTTP che potrebbero essere restituiti dall'oggetto richiesta (es: 500 -> potrebbe essere necessario riprovare, 404 -> non riprovare)
JulienV

236

Nell'ultima versione di Panda ( 0.19.2) è possibile passare direttamente l'URL

import pandas as pd

url="https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv"
c=pd.read_csv(url)

sembra che usare questo direttamente invece delle richieste direttamente non usi request-cache anche se usato
shadi

5
Quel codice ritorna a urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)>causa del protocollo https che urllib non può gestire.
multigoodverse,

Per quelli che usano Python 2, dovrai usare Python 2.7.10+.
avelis,

Sembra che ci sia qualche problema nella lettura di CSV da un URL. Ho letto il file una volta da un archivio locale e una volta dall'URL, ho continuato a ricevere errori dall'URL. Ho quindi abilitato error_bad_lines = False e oltre il 99% dei dati è stato ignorato. L'URL è link . Dopo aver letto il file, la forma del set di dati è stata trovata (88,1), il che è completamente sbagliato
Rishik Mani,

10

Come ho commentato, è necessario utilizzare un oggetto StringIO e decodificare, ad esempio c=pd.read_csv(io.StringIO(s.decode("utf-8")))se si utilizzano richieste, è necessario decodificare come .content restituisce byte se si utilizza .text, è sufficiente passare s come s = requests.get(url).textc = pd.read_csv(StringIO(s)).

Un approccio più semplice è passare l'URL corretto dei dati grezzi direttamente a read_csv, non è necessario passare un file come oggetto, è possibile passare un url in modo da non aver bisogno di richieste:

c = pd.read_csv("https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv")

print(c)

Produzione:

                              Country         Region
0                             Algeria         AFRICA
1                              Angola         AFRICA
2                               Benin         AFRICA
3                            Botswana         AFRICA
4                             Burkina         AFRICA
5                             Burundi         AFRICA
6                            Cameroon         AFRICA
..................................

Dai documenti :

filepath_or_buffer :

string o handle di file / StringIO La stringa potrebbe essere un URL. Gli schemi URL validi includono http, ftp, s3 e file. Per gli URL dei file, è previsto un host. Ad esempio, un file locale potrebbe essere il file: //localhost/path/to/table.csv


1
Puoi inviare l'URL direttamente a Panda read_csv! ovviamente! è una soluzione molto più semplice di quella che ho trovato! : D
PabTorre,

1
@pabtorre, sì, un esempio del perché leggere i documenti è una buona idea.
Padraic Cunningham,

6

Il problema che stai riscontrando è che l'output che ottieni nella variabile 's' non è un csv, ma un file html. Per ottenere il csv non elaborato, devi modificare l'URL in:

" https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv "

Il tuo secondo problema è che read_csv si aspetta un nome file, possiamo risolverlo usando StringIO dal modulo io. Il terzo problema è che request.get (url) .content fornisce un flusso di byte, possiamo invece risolverlo usando request.get (url) .text.

Il risultato finale è questo codice:

from io import StringIO

import pandas as pd
import requests
url='https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv'
s=requests.get(url).text

c=pd.read_csv(StringIO(s))

produzione:

>>> c.head()
    Country  Region
0   Algeria  AFRICA
1    Angola  AFRICA
2     Benin  AFRICA
3  Botswana  AFRICA
4   Burkina  AFRICA


0

Per importare dati tramite URL in panda basta applicare il semplice codice sottostante che funziona davvero meglio.

import pandas as pd
train = pd.read_table("https://urlandfile.com/dataset.csv")
train.head()

Se riscontri problemi con dati non elaborati, inserisci semplicemente "r" prima dell'URL

import pandas as pd
train = pd.read_table(r"https://urlandfile.com/dataset.csv")
train.head()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.