Панды read_csv из URL

139

Я использую Python 3.4 с IPython и имею следующий код. Я не могу прочитать csv-файл по указанному URL:

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)

У меня следующая ошибка

«Ожидаемый путь к файлу или файлоподобный объект, полученный тип»

Как я могу это исправить?

яд
источник
Вам нужно что-то подобное, c=pd.read_csv(io.StringIO(s.decode("utf-8")))но вы получаете html обратно, а не файл CSV, поэтому он не будет работать
Padraic Cunningham
3
Я вполне уверен, что URL, который вы хотите "https://raw.github.com/cs109/2014_data/blob/master/countries.csv".
kylie.a
@venom, выбрал более популярный ответ как правильный
ibodi

Ответы:

167

Обновить

Из панд 0.19.2теперь вы можете просто передать URL напрямую .


Как и следует из ошибки, pandas.read_csvв качестве первого аргумента необходим файлоподобный объект.

Если вы хотите прочитать csv из строки, вы можете использовать io.StringIO(Python 3.x) или StringIO.StringIO(Python 2.x) .

Кроме того, для URL - https://github.com/cs109/2014_data/blob/master/countries.csv - вы получаете htmlответ, а не raw csv, вы должны использовать URL, указанный в Rawссылке на странице github для получить сырой ответ CSV, который является - https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv

Пример -

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')))
Ананд С Кумар
источник
Что если ответ велик, и я хочу передать его вместо использования памяти для закодированного контента, декодированного контента и объекта StringIO?
акайхола
9
В последней версии панд вы можете дать URL-адрес непосредственно, т.е.c=pd.read_csv(url)
Inodb
Любопытно, что у меня есть более новая версия pandas(0.23.4), но я не мог дать URL-адрес напрямую. Этот ответ помог мне получить эту работу.
Антти
1
«Обновление от панд 0.19.2 теперь вы можете просто передать URL напрямую». Если вы не можете, потому что вам нужно передать аргументы аутентификации, в этом случае оригинальный пример очень нужен.
Аарон Холл
Это решение по-прежнему полезно, если вам нужна лучшая обработка ошибок с использованием HTTP-кодов, которые могут быть возвращены объектом запроса (например, 500 -> может потребоваться
повторная попытка
236

В последней версии панд ( 0.19.2) вы можете напрямую передать URL

import pandas as pd

url="https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv"
c=pd.read_csv(url)
inodb
источник
кажется, что использование этого напрямую вместо запросов напрямую не использует кеш запросов, даже если он используется
shadi
5
Этот код возвращается urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)>из-за протокола https, который urllib не может обработать.
мультигудверс
Для тех, кто использует Python 2, вам придется использовать Python 2.7.10+.
Авелис
Кажется, есть некоторые проблемы с чтением CSV с URL. Я прочитал файл один раз из локального хранилища и один раз из URL, я продолжал получать ошибки из URL. Затем я включил error_bad_lines = False, и более 99% данных были проигнорированы. URL является ссылкой . Когда я прочитал файл, форма набора данных оказалась (88,1), что совершенно неверно
Rishik Mani
10

Как я уже говорил, вам нужно использовать объект StringIO и декодировать, т.е. c=pd.read_csv(io.StringIO(s.decode("utf-8")))если вы используете запросы, вам нужно декодировать как .content возвращает байты, если вы используете .text, вам просто нужно передать s как s = requests.get(url).textc = pd.read_csv(StringIO(s)).

Более простой подход - передать правильный URL-адрес необработанных данных напрямую read_csv, вам не нужно передавать файл, подобный объекту, вы можете передать URL-адрес, чтобы вам вообще не нужны запросы:

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

print(c)

Вывод:

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

Из документов :

filepath_or_buffer :

дескриптор строки или файла / StringIO Строка может быть URL-адресом. Допустимые схемы URL включают http, ftp, s3 и file. Для файловых URL-адресов ожидается хост. Например, локальный файл может быть файлом: //localhost/path/to/table.csv

Падрайк Каннингем
источник
1
Вы можете передать URL непосредственно пандам read_csv! конечно! это гораздо более простое решение, чем то, которое я нашел! : D
PabTorre
1
@pabtorre, да, пример того, почему чтение документов является хорошей идеей.
Падрайк Каннингем
6

Проблема, с которой вы столкнулись, заключается в том, что вывод, который вы получаете в переменную 's', - это не CSV, а HTML-файл. Для того, чтобы получить сырой CSV, вы должны изменить URL:

' Https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv '

Ваша вторая проблема заключается в том, что read_csv ожидает имя файла, мы можем решить это, используя StringIO из модуля io. Третья проблема заключается в том, что request.get (url) .content доставляет поток байтов, мы можем решить эту проблему, используя вместо этого request.get (url) .text.

Конечный результат - это код:

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

вывод:

>>> c.head()
    Country  Region
0   Algeria  AFRICA
1    Angola  AFRICA
2     Benin  AFRICA
3  Botswana  AFRICA
4   Burkina  AFRICA
PabTorre
источник
2
url = "https://github.com/cs109/2014_data/blob/master/countries.csv"
c = pd.read_csv(url, sep = "\t")
Гурсимран Сингх
источник
Пожалуйста, объясните, как работает ваше решение.
Селим Йылдыз
0

Чтобы импортировать данные через URL в пандах, просто примените простой код ниже, он работает на самом деле лучше.

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

Если у вас возникли проблемы с необработанными данными, просто поставьте «r» перед URL

import pandas as pd
train = pd.read_table(r"https://urlandfile.com/dataset.csv")
train.head()
Jain
источник