Dask groupby 变换

Dask groupby transform

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

比如。我想要这个 table

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 对象,它为我们提供了与原始数据框相同的行数。

在 pandas 我可以做以下事情

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

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

谢谢。

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

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