使用groupby并对大型数据集应用自定义函数并避免混洗的有效方法是什么?

时间:2019-01-12 23:38:40

标签: python pandas data-science dask

我试图在庞大的数据集上使用groupbyapply的自定义函数,这给了我内存错误,并且由于改组,工作人员被杀死。我该如何避免混洗并有效地做到这一点。

我正在读取大约50个700MB(每个)实木复合地板文件,这些文件中的数据是隔离的,即,一个以上的文件中不存在任何组。如果我尝试在一个文件上运行代码,则可以正常运行,但在尝试在完整数据集上运行时失败。

Dask文档讨论了在组上应用自定义函数时groupby的问题,但它们没有为此类数据提供解决方案: http://docs.dask.org/en/latest/dataframe-groupby.html#difficult-cases

如何在合理的时间范围内处理我的数据集(将groupby-apply应用于单个文件大约需要6分钟),并希望避免随机播放。我不需要对结果进行排序,也不需要groupby尝试对来自不同文件的完整数据集进行排序。

我尝试使用persist,但数据不适合RAM(32GB)。尽管dask不支持多列索引,但是我尝试在一个列上添加索引以支持groupby无济于事。下面是代码的结构:

from dask.dataframe import read_parquet

df = read_parquet('s3://s3_directory_path')
results = df.groupby(['A', 'B']).apply(custom_function).compute()

# custom function sorts the data within a group (the groups are small, less than 50 entries) on a field and computes some values based on heuristics (it computes 4 values, but I am showing 1 in example below and other 3 calculations are similar)

def custom_function(group):
    results = {}
    sorted_group = group.sort_values(['C']).reset_index(drop=True)
    sorted_group['delta'] = sorted_group['D'].diff()
    sorted_group.delta = sorted_group.delta.shift(-1)
    results['res1'] = (sorted_group[sorted_group.delta < -100]['D'].sum() - sorted_group.iloc[0]['D'])
    # similarly 3 more results are generated
    results_df = pd.DataFrame(results, index=[0])
    return results_df

一种可能性是我一次处理一个文件并多次处理,但是在那种情况下,dask似乎毫无用处(没有并行处理),并且要花费几个小时才能达到所需的结果。有什么办法可以使用dask或其他任何库来有效地做到这一点?人们如何处理此类数据?

1 个答案:

答案 0 :(得分:0)

如果您想避免改组并且可以保证各组之间的隔离度很好,那么您可以通过map_partitions在每个分区上调用pandas groupby

df.map_partitions(lambda part: part.groupby(...).apply(...))