使用 pandas.read_csv 从 URL 读取压缩的 CSV 文件时出错

Posted

技术标签:

【中文标题】使用 pandas.read_csv 从 URL 读取压缩的 CSV 文件时出错【英文标题】:Error while reading compressed CSV file from URL with pandas.read_csv 【发布时间】:2014-03-03 18:37:13 【问题描述】:

我正在尝试使用 pandas.read_csv 从 IPython 笔记本中的 URL(在本例中为 GitHub 原始 URL)读取 bz2 压缩的 CSV 文件,但出现以下错误:

Python cannot read bz2 from open file handle

我进行了一些研究,但我似乎无法找出问题所在。我已经尝试手动解压缩 bz2 文件,我知道它们没有损坏或其他错误,而且我还知道 URL 的格式正确 - 如果我将它们输入到浏览器中,它会正确下载文件。

这是我的 IPython 笔记本中的代码:

import pandas, bz2, urllib2
datafiles = 
for filename in csvData['Filename']:
    csvUrl = 'https://raw.github.com/hawkw/traverse/master/data/' + filename
    try:
        datafiles[filename] = pandas.read_csv(csvUrl, compression='bz2')
        print (datafiles[filename])
    except Exception as e:
        print("Caught error \"error\" at url".format(error=e, url=csvUrl))

还有输出:

Caught error "Python cannot read bz2 from open file handle" at https://raw.github.com/hawkw/traverse/master/data/-Users-hawk-_2014-02-05.csv.bz2
Caught error "Python cannot read bz2 from open file handle" at https://raw.github.com/hawkw/traverse/master/data/-Users-Owner_2014-02-05.csv.bz2
Caught error "Python cannot read bz2 from open file handle" at https://raw.github.com/hawkw/traverse/master/data/-Users-will_2014-02-05.csv.bz2
Caught error "Python cannot read bz2 from open file handle" at https://raw.github.com/hawkw/traverse/master/data/-Users-hawk_2014-02-06.csv.bz2
Caught error "Python cannot read bz2 from open file handle" at https://raw.github.com/hawkw/traverse/master/data/-Users-hawk-Documents_2014-02-06.csv.bz2
Caught error "Python cannot read bz2 from open file handle" at https://raw.github.com/hawkw/traverse/master/data/-home-w-weismanm_2014-02-05.csv.bz2
Caught error "Python cannot read bz2 from open file handle" at https://raw.github.com/hawkw/traverse/master/data/-home-w-weismanm_2014-02-06.csv.bz2

有人知道我做错了什么吗?

编辑:我尝试像这样使用urllib2 打开文件,正如@edchum 建议的那样:

datafiles = 

for filename in csvData['Filename']:

    url = 'https://raw.github.com/hawkw/traverse/master/data/' + filename

    try:
        response = urllib2.urlopen(url)
    except HTTPError as e:
        print ("Caught HTTPError", e)
    else:
        try:
            datafiles[filename] = pandas.read_csv(response, compression='bz2')
            print (datafiles[filename])
        except Exception as e:
            print("Caught error \"0\" at 1".format(e,url))

但它仍然没有工作,失败并出现同样的错误。作为旁注,pandas.read_csv() 说它可以从文档中的 URL 打开文件。

【问题讨论】:

嗯.. 我收回我之前的评论,我得到了和你一样的错误,它应该可以工作,可能是 Pandas 中的错误 @EdChum:是的,我看到了你的建议,我尝试这样做,但它仍然没有用。为我的帖子添加了编辑。 我在本地下载了你的一个文件,它解压得很好,这看起来像是read_csv 处理 url 句柄的错误 @EdChum:好的,你有什么建议?我对 Pandas 很陌生。 你可以看看这是否只是url打开或压缩的问题,所以在GitHub上保存一个不压缩的小样本csv,看看它是否可以打开它。否则我会在本地加载并保存 csv,然后循环打开它们,Pandas 看起来可以处理得很好 【参考方案1】:

如果您出于某种原因绝对不能简单地下载文件,并且必须不断从远程源(不是很近)拉取它们,那么如果需要,您可以在内存中完成所有操作:

>>> import pandas as pd
>>> import io
>>> import urllib2
>>> import bz2
>>> 
>>> url = "https://github.com/hawkw/traverse/blob/master/data/-Users-hawk_2014-02-06.csv.bz2?raw=true"
>>> raw_data = urllib2.urlopen(url).read()
>>> data = bz2.decompress(raw_data)
>>> df = pd.read_csv(io.BytesIO(data))
>>> df.head()
                                                path  st_mode    st_ino  \
0  /Users/hawk/Library/minecraft/bin/minecraft/mo...    33261  59612469   
1  /Users/hawk/Library/Application Support/Google...    16832  91818463   
2  /Users/hawk/Library/Caches/Metadata/Safari/His...    33188  95398522   
3  /Users/hawk/Documents/Minecraft1.6.4/assets/so...    33188  90620503   
4  /Users/hawk/Library/Caches/Metadata/Safari/His...    33188  96129272   

     st_dev  st_nlink  st_uid  st_gid  st_size    st_atime    st_mtime  \
0  16777219         1     501      20     2626  1370201925  1366983504   
1  16777219         3     501      20      102  1391697388  1384638452   
2  16777219         1     501      20    36758  1389032348  1389032363   
3  16777219         1     501      20    12129  1387000073  1384114141   
4  16777219         1     501      20      170  1390545751  1390545751   

     st_ctime  
0  1368736019  
1  1384638452  
2  1389032363  
3  1384114141  
4  1390545751  

[5 rows x 11 columns]

您希望在哪里传递适当的encoding 参数。

【讨论】:

非常感谢,这行得通!仅供参考,这些文件是从远程源中提取的,因为我希望能够分发笔记本,并且源存储库目录中的文件会发生变化。

以上是关于使用 pandas.read_csv 从 URL 读取压缩的 CSV 文件时出错的主要内容,如果未能解决你的问题,请参考以下文章

pandas.read_csv 报ssl.SSLError

Pandas `read_csv` 方法使用了太多 RAM

如何让 pandas.read_csv() 从 CSV 文件列中推断 datetime 和 timedelta 类型?

有没有办法从 pandas read_csv 中“提取”dtype 转换功能?

如何在 pandas.read_csv 的标题之前跳过未知数量的空行?

如何使用 pandas.read_csv() 将索引数据读取为字符串?