从 iPython Notebook 下载 CSV

Posted

技术标签:

【中文标题】从 iPython Notebook 下载 CSV【英文标题】:Download CSV from an iPython Notebook 【发布时间】:2015-10-31 20:30:51 【问题描述】:

我运行一个 iPython Notebook 服务器,并希望用户能够将 pandas 数据帧下载为 csv 文件,以便他们可以在自己的环境中使用它。没有个人数据,所以如果解决方案涉及在服务器上写入文件(我可以这样做)然后下载该文件,我会很高兴的。

【问题讨论】:

我认为 ipython 没有任何功能可以解决您的问题,但您始终可以在 python 中编写一个执行下载的例程,并将其包含在您的用户的笔记本中。只是一个想法。希望对您有所帮助。 感谢 lrnzcig:这就是我的样子。我可以试试你的建议。 您好,是否可以使用pd.to_csv() 将数据帧写入csv,然后直接从ipython 服务器打开csv,然后文件>下载? 【参考方案1】:

如何使用 IPython 中的 FileLinks 类?我使用它来直接从 Jupyter 笔记本中访问数据。假设您的数据在 pandas 数据框 p_df 中:

from IPython.display import FileLink, FileLinks

p_df.to_csv('/path/to/data.csv', index=False)
p_df.to_excel('/path/to/data.xlsx', index=False)

FileLinks('/path/to/')

将其作为笔记本单元运行,结果将是指向可直接从笔记本下载的文件的链接列表。 '/path/to' 当然需要笔记本用户可以访问。

【讨论】:

从 IPython.display 导入文件链接,文件链接 这在 nbviewer 中不起作用(因为它试图处理它但不知道如何处理)。对于 nbviewer,您可以使用以下代码片段。它只是在 URL 的末尾添加?download...gitlab.tetras-libre.fr/tetras-libre/jupyter/nbviewer/snippets/4 @daxid 这只是一个登录页面【参考方案2】:

对于不太大的表可以使用以下代码:

import base64
import pandas as pd
from IPython.display import html

def create_download_link( df, title = "Download CSV file", filename = "data.csv"):
    csv = df.to_csv()
    b64 = base64.b64encode(csv.encode())
    payload = b64.decode()
    html = '<a download="filename" href="data:text/csv;base64,payload" target="_blank">title</a>'
    html = html.format(payload=payload,title=title,filename=filename)
    return HTML(html)

df = pd.DataFrame(data = [[1,2],[3,4]], columns=['Col 1', 'Col 2'])
create_download_link(df)

【讨论】:

不错!大文件呢? :) 直到本周,这种方法在 Databricks 中对我来说一直很有效。现在我在 Databricks 中运行它后,下载按钮就不会出现了。 ***.com/a/35760941/6178021 -- 这对我有用! 像魅力一样工作。谢谢【参考方案3】:

如果你想避免在服务器上存储 CSV,你可以使用这个在客户端创建 CSV 的 javascript 替代方案:

from IPython.display import Javascript
js_download = """
var csv = '%s';

var filename = 'results.csv';
var blob = new Blob([csv],  type: 'text/csv;charset=utf-8;' );
if (navigator.msSaveBlob)  // IE 10+
    navigator.msSaveBlob(blob, filename);
 else 
    var link = document.createElement("a");
    if (link.download !== undefined)  // feature detection
        // Browsers that support HTML5 download attribute
        var url = URL.createObjectURL(blob);
        link.setAttribute("href", url);
        link.setAttribute("download", filename);
        link.style.visibility = 'hidden';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    

""" % data_in_dataframes.to_csv(index=False).replace('\n','\\n').replace("'","\'")

Javascript(js_download)

基本上,它从 pd 数据帧在 python 中创建一个 CSV 字符串,并在一个小的 js 脚本中使用它 creates a CSV file on the client side 并打开一个保存对话框以将其保存在用户计算机上。我在我的 iPython 环境中进行了测试,它就像一个魅力!


请注意,我正在转义 \n。如果我不这样做,js 脚本字符串将多行写入 CSV 变量。

例如,print "var csv = '%s'" % industries_revenues.to_csv(index=False).replace('\n','\\n') 结果如下:

var csv = 'Industry,sum_Amount\nBanking,65892584.0\n(...)Finance,20211917.0\n'

而不是 print "var csv = '%s'" % industries_revenues.to_csv(index=False) 没有 \n 转义会导致多行并因此出错 javascript:

var csv = 'Industry,sum_Amount
Banking,65892584.0
(...)
Finance,20211917.0
'

我还转义了',以免破坏javascript中的变量字符串。

【讨论】:

添加输出时出现 Javascript 错误!语法错误:缺少; before 语句 有关详细信息,请参阅您的浏览器 Javascript 控制台。 我还要添加 .replace('\r','')。在 Windows 中,pandas 会为行尾生成 \r\n,这可能会导致 javascript 混淆。【参考方案4】:

一个创建 csv 下载链接的函数,基于 Coen Jonker 的回答,类似于 Yasin Zähringer 的回答,只是它使用 IPython.display.FileLink,因此无需创建 html 代码。

该功能有一个可选的删除提示,因此您可以在下载后删除文件以保持笔记本服务器干净。

# Import a module to create a data frame
import pandas
# Import a module to display a link to the file
from IPython.display import FileLink
# Import a module to delete the file
import os
# Create a download function
def csv_download_link(df, csv_file_name, delete_prompt=True):
    """Display a download link to load a data frame as csv within a Jupyter notebook

    Parameters
    ----------
    df : pandas data frame
    csv_file_name : str
    delete_prompt : bool
    """
    df.to_csv(csv_file_name, index=False)
    display(FileLink(csv_file_name))
    if delete_prompt:
        a = input('Press enter to delete the file after you have downloaded it.')
        os.remove(csv_file_name)

# Create an example data frame
df = pandas.DataFrame('x':[1,2,3],'y':['a','b','c'])
# Use the function to diplay a download link
csv_download_link(df, 'file_name.csv')

这主要适用于在自己的机器上使用 jupyter notebook 的人。在共享计算机上,使用os.remove 可能会出现问题,具体取决于您设置文件写入权限的方式。

【讨论】:

【参考方案5】:

您可以使用 notebook 可以显示对象的 html 和数据 url 的事实来使 csv 的内容可下载:

import urllib

class CSV(object):
    def _repr_html_(self):
        html = []

        html.append(",,".format(
                "user",
                "age",
                "city"
            )
        )

        html.append(",,".format(
                "Alice",
                "39",
                "New York"
            )
        )

        html.append(",,".format(
                "Bob",
                "30",
                "Denver"
            )
        )

        html.append(",,".format(
                "Carol",
                "27",
                "Tulsa"
            )
        )


        export = '\n'.join(html)
        export = urllib.quote(export.encode("utf-8"))
        csvData = 'data:application/csv;charset=utf-8,' + export
        return "<a download='export.csv' href='' target='_blank'>csv file</a>".format(csvData)

CSV()

【讨论】:

【参考方案6】:

我找到的简单方法是:

df.to_csv('~/Desktop/file_name.csv')

【讨论】:

【参考方案7】:

我从 jupyter notebook 下载所有文件的简单方法是使用这个美妙的命令

!tar cvfz my_compressed_file_name.tar.gz *

这将下载服务器的所有文件,包括笔记本。

如果您的服务器有多个文件夹,您可能愿意使用以下命令。为目录的每一步写上 ../ 在 * 之前。

tar cvfz zipname.tar.gz ../../*

希望对你有帮助..

【讨论】:

我想说,一旦你完成了上述步骤,你就可以去文件部分并在一个 tar 中下载所有文件,而不是单独下载文件

以上是关于从 iPython Notebook 下载 CSV的主要内容,如果未能解决你的问题,请参考以下文章

ipython notebook pandas max 允许的列数

ipython notebook 安装求助

如何安装ipython notebook

toPandas() 在 Jupyter iPython Notebook 上工作,但提交失败 - AWS EMR

ipython notebook环境搭建

如何在win7 64下安装ipython notebook