Pandas 从 URL 读取 csv
- 2025-01-07 08:44:00
- admin 原创
- 105
问题描述:
我正在尝试使用 Python 3.x 从给定的 URL 读取 csv 文件:
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)
我有以下错误
“预期文件路径名或类似文件的对象,得到 <class 'bytes'> 类型”
我该如何解决这个问题?我使用的是 Python 3.4
解决方案 1:
在最新版本的 pandas ( 0.19.2
) 中,你可以直接传递 url
import pandas as pd
url = "https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv"
c = pd.read_csv(url)
解决方案 2:
更新0.19.2
:现在您可以从 pandas直接传递read_csv()
url,但如果需要身份验证,则此操作将会失败。
对于较旧的 pandas 版本,或者如果您需要身份验证,或者出于任何其他 HTTP 容错原因:
使用pandas.read_csv
类似文件的对象作为第一个参数。
如果您想从字符串读取 csv,可以使用
io.StringIO
。对于 URL
https://github.com/cs109/2014_data/blob/master/countries.csv
,您将获得html
响应,而不是原始csv;您应该使用 github 页面中的链接提供的 urlRaw
来获取原始 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')))
注意:在 Python 2.x 中,字符串缓冲区对象StringIO.StringIO
解决方案 3:
正如我所评论的,您需要使用一个 StringIO 对象并进行解码,即,c=pd.read_csv(io.StringIO(s.decode("utf-8")))
如果使用请求,您需要解码为 .content 返回字节,如果您使用 .text,您只需要按原样传递 s s = requests.get(url).text
c = 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
..................................
来自 文档:
文件路径或缓冲区:
字符串或文件句柄 / StringIO 字符串可以是 URL。有效的 URL 方案包括 http、ftp、s3 和文件。对于文件 URL,需要主机。例如,本地文件可以是 file ://localhost/path/to/table.csv
解决方案 4:
您遇到的问题是,变量“s”中的输出不是 csv,而是 html 文件。为了获取原始 csv,您必须将 url 修改为:
' https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv '
您的第二个问题是 read_csv 需要文件名,我们可以通过使用 io 模块中的 StringIO 来解决这个问题。第三个问题是 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
解决方案 5:
url = "https://github.com/cs109/2014_data/blob/master/countries.csv"
c = pd.read_csv(url, sep = " ")
解决方案 6:
要在 pandas 中通过 URL 导入数据,只需应用下面简单的代码,效果实际上更好。
import pandas as pd
train = pd.read_table("https://urlandfile.com/dataset.csv")
train.head()
如果你对原始数据有问题,那么只需在 URL 前加上“r”
import pandas as pd
train = pd.read_table(r"https://urlandfile.com/dataset.csv")
train.head()