Python pandas中的并行read_表

Python pandas中的并行read_表,python,numpy,pandas,Python,Numpy,Pandas,有没有办法并行化read_table()的调用?在我的例子中,由于日期解析,它是CPU绑定的。我看不出通过阅读文档来实现这一点的任何方法。唯一想到的是拆分输入文件,并行调用read_table,然后连接数据帧。这将并行读取CSV文件并连接它们。令人恼火的是,它不能处理numpy类型,因此不能解析日期。我一直在努力解决同样的问题,但到目前为止,像execnet这样的库似乎无法处理非内置类型。这就是为什么我在发送之前将数据帧转换为json。它将类型剥离为基本的Python类型 编辑:如果需要解析日期

有没有办法并行化read_table()的调用?在我的例子中,由于日期解析,它是CPU绑定的。我看不出通过阅读文档来实现这一点的任何方法。唯一想到的是拆分输入文件,并行调用read_table,然后连接数据帧。

这将并行读取CSV文件并连接它们。令人恼火的是,它不能处理
numpy
类型,因此不能解析日期。我一直在努力解决同样的问题,但到目前为止,像
execnet
这样的库似乎无法处理非内置类型。这就是为什么我在发送之前将数据帧转换为
json
。它将类型剥离为基本的Python类型

编辑:如果需要解析日期,可能更明智的方法是远程读取
CSV
文件,解析日期并将其保存为
pickle
到硬盘。然后您可以读取主进程中的pickle文件并将它们连接起来。我还没有试过这样做,看它是否能提高性能

远程读取csv.py

import cPickle as pickle

if __name__ == '__channelexec__':
    reader = pickle.loads(channel.receive())

    for filename in channel:
        channel.send(reader(filename).to_json())
下面使用上面的模块。我在IPython进行了测试

from pandas import DataFrame, concat, read_csv, read_json
from numpy import random
import execnet
import remote_read_csv
import cPickle as pickle
import itertools
import psutil

### Create dummy data and save to CSV

def rdf():
    return DataFrame((random.rand(4, 3) * 100).astype(int))

d1 = rdf()
d2 = rdf()
d3 = rdf()

dfsl = [d1, d2, d3]
names = 'd1.csv d2.csv d3.csv'.split()
for i in range(3):
    dfsl[i].to_csv(names[i])

### Read CSV files in separate threads then concatenate

reader = pickle.dumps(read_csv)

def set_gateways(remote_module, *channel_sends):
    gateways = []
    channels = []
    for i in range(psutil.NUM_CPUS):
        gateways.append(execnet.makegateway())
        channels.append(gateways[i].remote_exec(remote_module))
        for send in channel_sends:
            channels[i].send(send)
    return (gateways, channels)

def para_read(names):
    gateways, channels = set_gateways(remote_read_csv, reader)
    mch = execnet.MultiChannel(channels)
    queue = mch.make_receive_queue()
    channel_ring = itertools.cycle(mch)
    for f in names:
        channel = channel_ring.next()
        channel.send(f)
    dfs = []
    for i in range(len(names)):
        channel, df = queue.get()
        dfs.append(df)

    [gw.exit() for gw in gateways]
    return concat([read_json(i) for i in dfs], keys=names)

para_read(names)

这将并行读取CSV文件并连接它们。令人恼火的是,它不能处理
numpy
类型,因此不能解析日期。我一直在努力解决同样的问题,但到目前为止,像
execnet
这样的库似乎无法处理非内置类型。这就是为什么我在发送之前将数据帧转换为
json
。它将类型剥离为基本的Python类型

编辑:如果需要解析日期,可能更明智的方法是远程读取
CSV
文件,解析日期并将其保存为
pickle
到硬盘。然后您可以读取主进程中的pickle文件并将它们连接起来。我还没有试过这样做,看它是否能提高性能

远程读取csv.py

import cPickle as pickle

if __name__ == '__channelexec__':
    reader = pickle.loads(channel.receive())

    for filename in channel:
        channel.send(reader(filename).to_json())
下面使用上面的模块。我在IPython进行了测试

from pandas import DataFrame, concat, read_csv, read_json
from numpy import random
import execnet
import remote_read_csv
import cPickle as pickle
import itertools
import psutil

### Create dummy data and save to CSV

def rdf():
    return DataFrame((random.rand(4, 3) * 100).astype(int))

d1 = rdf()
d2 = rdf()
d3 = rdf()

dfsl = [d1, d2, d3]
names = 'd1.csv d2.csv d3.csv'.split()
for i in range(3):
    dfsl[i].to_csv(names[i])

### Read CSV files in separate threads then concatenate

reader = pickle.dumps(read_csv)

def set_gateways(remote_module, *channel_sends):
    gateways = []
    channels = []
    for i in range(psutil.NUM_CPUS):
        gateways.append(execnet.makegateway())
        channels.append(gateways[i].remote_exec(remote_module))
        for send in channel_sends:
            channels[i].send(send)
    return (gateways, channels)

def para_read(names):
    gateways, channels = set_gateways(remote_read_csv, reader)
    mch = execnet.MultiChannel(channels)
    queue = mch.make_receive_queue()
    channel_ring = itertools.cycle(mch)
    for f in names:
        channel = channel_ring.next()
        channel.send(f)
    dfs = []
    for i in range(len(names)):
        channel, df = queue.get()
        dfs.append(df)

    [gw.exit() for gw in gateways]
    return concat([read_json(i) for i in dfs], keys=names)

para_read(names)

不仅供参考,如果您正在传递格式,则在之后(通过
pd.to_datetime
)进行日期解析会更快。在任何情况下,拆分和连接都是有效的解决方案。从apply调用pd.to_datetime是否允许在导入后更轻松地进行并行化,或者您仍然需要手动将数据帧拆分为N/M个部分(N=num行,M=num逻辑过程)并在之后执行?我真的希望一些简单的并行化案例能够得到一些scikit学习函数(比如gridsearch)所具有的n_作业类型的支持;仅供参考,如果您正在传递格式,则在之后(通过
pd.to_datetime
)进行日期解析会更快。在任何情况下,拆分和连接都是有效的解决方案。从apply调用pd.to_datetime是否允许在导入后更轻松地进行并行化,或者您仍然需要手动将数据帧拆分为N/M个部分(N=num行,M=num逻辑过程)并在之后执行?我真的希望一些简单的并行化案例能够得到一些scikit学习函数(比如gridsearch)所具有的n_作业类型的支持。是的,我希望看到sklearn风格的并行化。