使用dask hdf / parquet的Python大数据集功能工程工作流程

时间:2018-03-29 10:55:05

标签: python pandas dask hdf feature-engineering

SO已经有一个很好的问题,但最好的答案现在是5年了,所以我认为2018年应该有更好的选择。

我目前正在寻找一个大于内存数据集的特征工程管道(使用合适的dtypes)。

初始文件是不适合内存的csv。以下是我的需求:

  1. 创建功能(主要使用多列上的groupby操作。)
  2. 将新功能合并到之前的数据(在磁盘上,因为它不适合内存)
  3. 对某些ML应用程序使用子集(或所有)列/索引
  4. 重复1/2/3(这是一个迭代过程,如day1:创建4 功能,第2天:再创建4个......)
  5. 尝试镶木地板和木桶:

    首先,我将大csv文件拆分为多个小“拼花”文件。有了这个,dask对于新功能的计算非常有效,但是,我需要将它们合并到初始数据集和atm,我们不能将新列添加到镶木地板文件中。通过块读取csv,合并和重新保存到多个镶木地板文件太耗时,因为特征工程是此项目中的迭代过程。

    尝试使用HDF和dask:

    然后我转向HDF,因为我们可以添加列并使用特殊查询,它仍然是二进制文件存储。我再次将大csv文件拆分为多个HDF,并使用相同的key ='base'作为基本功能,以便使用与DASK的并发写入(HDF不允许)。

    data = data.repartition(npartitions=10) # otherwise it was saving 8Mo files using to_hdf
    data.to_hdf('./hdf/data-*.hdf', key='base', format='table', data_columns=['day'], get=dask.threaded.get)
    

    附件查询:指定data_columns对于dask似乎没用,因为dask.read_hdf中没有“where”?

    与我的预期不同,我无法将新功能合并到具有以下代码的倍数小文件中:

    data = dd.read_hdf('./hdf/data-*.hdf', key='base')
    data['day_pow2'] = data['day']**2
    data['day_pow2'].to_hdf('./hdf/data-*.hdf', key='added', get=dask.threaded.get) 
    

    使用dask.threaded我在2%之后得到“python停止工作”。 使用dask.multiprocessing.get需要永远并创建新文件

    此工作流程中最合适的工具(存储和处理)是什么?

2 个答案:

答案 0 :(得分:1)

我将在fastparquet上复制related issue的评论:技术上可以在现有的镶木地板数据集中添加列,但这不是在fastparquet中实现的,也可能不在任何其他镶木地板中实现实施要么。

使代码执行此操作可能不会太繁重(但目前尚未规划):对write columns的调用是按顺序发生的,因此用于写入的新列需要与此函数一起渗透到此函数中文件位置对应于页脚中元数据的当前第一个字节。另外,架构需要单独更新(这很简单)。需要对数据集的每个文件重复该过程。这不是答案"对于这个问题,但也许是有人想要承担这项任务。

答案 1 :(得分:0)

我会认真考虑使用数据库(索引访问)作为存储,甚至使用Apache Spark(以分布式/集群方式处理数据)和Hive / Impala作为后端......