可以结合使用Paramiko和Dask的read_csv()方法从远程服务器读取.csv吗?

时间:2019-06-16 23:21:06

标签: python pandas ssh paramiko dask

今天,我开始使用 Dask Paramiko 软件包,部分是作为学习练习,部分是因为我正在开始一个需要处理大型数据集的项目(仅可从远程VM访问(即不能在本地存储)的10s GB)(我具有登录凭据以及该VM的sudo权限。我只有很少的数据分析经验,也没有使用过几千行数据集的经验。

以下代码段属于一个简短的帮助程序,该程序将使VM上托管的大型csv文件的数据帧变淡。我想稍后将其输出(对dask数据框的引用)传递给第二个函数,该函数将对其执行一些概述分析。

import dask.dataframe as dd
import paramiko as pm
import pandas as pd
import sys

def remote_file_to_dask_dataframe(remote_path):

   if isinstance(remote_path, (str)):
      try:
         client = pm.SSHClient()
         client.load_system_host_keys()
         client.connect('#myserver', username='my_username', password='my_password')
         sftp_client = client.open_sftp()
         remote_file = sftp_client.open(remote_path)
         df = dd.read_csv(remote_file)
         remote_file.close()
         sftp_client.close()
         return df 
      except:
         print("An error occurred.")
         sftp_client.close()
         remote_file.close()
   else:
      raise ValueError("Path to remote file as string required")

代码既不好也不完整,我会及时用ssh密钥替换用户名和密码,但这不是问题。在jupyter笔记本中,我以前打开了sftp连接,并提供了服务器上文件的路径,并通过常规的Pandas read_csv调用将其读取到数据帧中。但是,这里使用Dask的等效行是问题的根源:df = dd.read_csv(remote_file)

我已经在线查看了文档(here),但无法确定我上面尝试的是否可行。对于联网选项,Dask似乎需要一个URL。例如的参数传递选项S3,似乎取决于该基础架构的后端。不幸的是,我对 dash-ssh 文档(here)毫无意义。

我一直在研究打印语句,唯一无法执行的行是所述语句。出现的错误是: raise TypeError('URL类型无法理解:%s'%urlpath) TypeError:网址类型无法理解:

有人能指出我正确的方向来实现我的目标吗?我希望Dask的read_csv像Pandas的一样,因为它是基于Pandas的。

非常感谢您的帮助。

p.s。我知道Pandas的read_csv chunksize选项,但我想尽可能通过Dask实现。

2 个答案:

答案 0 :(得分:1)

在Dask的主版本中,文件系统操作现在使用fsspec,它与以前的实现(s3,gcs,hdfs)一起支持其他一些file-systems,请参见协议标识符fsspec.registry.known_implementations

简而言之,如果您是从master那里安装fsspec和Dask的,那么现在可以使用像“ sftp:// user:pw @ host:port / path”之类的url。

答案 1 :(得分:0)

似乎您必须实现他们的"file system" interface

我不确定为允许read_csv您需要实现的最小方法集是什么。但是您绝对必须实现open

class SftpFileSystem(object):
    def open(self, path, mode='rb', **kwargs):
        return sftp_client.open(path, mode)

dask.bytes.core._filesystems['sftp'] = SftpFileSystem

df = dd.read_csv('sftp://remote/path/file.csv')

有关完整的方法集,请参见implementation of LocalFileSystem