Dask groupby转换

时间:2018-04-17 11:07:03

标签: dask

我正在尝试计算由多列定义的分组的频率,我希望将频率输出到原始的dask数据帧。

例如。我想要这张桌子

ID      PayMethod  Day      
45      CC         Monday    
45      Cash       Monday   
45      CC         Tuesday   
57      Cash       Tuesday
57      Cash       Tuesday
69      CC         Saturday 
69      Cash       Sunday    

看起来像这样:

ID      PayMethod  Day      ID_PayMethod_Count ID_PayMethod_Day_Count
45      CC         Monday    2                 1
45      Cash       Monday    2                 1
45      CC         Tuesday   2                 1
57      Cash       Tuesday   2                 2
57      Cash       Tuesday   2                 2
69      CC         Saturday  1                 1
69      Cash       Sunday    1                 1

Groupby + transform为我们提供了一个groupby对象,它为我们提供了与原始数据帧相同的行数。

在熊猫中我可以做以下

df['ID_PayMethod_Count'] = df.groupby(['ID','PayMethod','Count']).transform(np.size)

目前Dask没有实现groupby转换方法。我想知道是否有替代方案,是否可以应用到某个地方或其他方式的某些矢量化操作。我知道这可以通过groupby / aggregation / merge操作完成,但我试图避免这种情况,因为它会导致内存问题并且操作无法完成(这些是大文件)。

感谢。

1 个答案:

答案 0 :(得分:2)

可以通过多种方法实现等效计算。以下是ID_PayMethod列的示例(我注意到您提供的数据中没有Count)

txt = """ID      PayMethod  Day
45      CC         Monday
45      Cash       Monday
45      CC         Tuesday
57      Cash       Tuesday
57      Cash       Tuesday
69      CC         Saturday
69      Cash       Sunday"""

# set up data
df = pd.read_table(io.StringIO(b), delim_whitespace=True)
d = dd.from_pandas(df, npartitions=2)

# return aggregate as a concrete pandas dataframe
counts = d.groupby(['ID', 'PayMethod']).count().compute()

# compute look of output, or supply directly if you know
meta = df.assign(ID_PayMethod=df.apply(
    lambda x: counts.loc[(x['ID'], x['PayMethod'])], axis=1))[:0]
# apply the "apply" to each chunk, using the computed counts
d.map_partitions(lambda ddd: ddd.assign(ID_PayMethod=ddd.apply(
    lambda x: counts.loc[(x['ID'], x['PayMethod'])], axis=1)), meta=meta)

对此最终输出执行.compute()会产生以下内容

   ID PayMethod       Day  ID_PayMethod
0  45        CC    Monday             2
1  45      Cash    Monday             1
2  45        CC   Tuesday             2
3  57      Cash   Tuesday             2
4  57      Cash   Tuesday             2
5  69        CC  Saturday             1
6  69      Cash    Sunday             1