聚合Dask数据帧并生成聚合的数据帧

时间:2017-09-23 02:15:32

标签: group-by aggregation dask

我有一个看起来像这样的Dask数据框:

url     referrer    session_id ts                  customer
url1    ref1        xxx        2017-09-15 00:00:00 a.com
url2    ref2        yyy        2017-09-15 00:00:00 a.com
url2    ref3        yyy        2017-09-15 00:00:00 a.com
url1    ref1        xxx        2017-09-15 01:00:00 a.com
url2    ref2        yyy        2017-09-15 01:00:00 a.com

我想将数据分组到url和timestamp,聚合列值并生成一个看起来像这样的数据框:

customer url    ts                  page_views visitors referrers
a.com    url1   2017-09-15 00:00:00 1          1        [ref1]
a.com    url2   2017-09-15 00:00:00 2          2        [ref2, ref3]

在Spark SQL中,我可以这样做:

select 
    customer,
    url,
    ts,
    count(*) as page_views,
    count(distinct(session_id)) as visitors,
    collect_list(referrer) as referrers
from df
group by customer, url, ts

有什么方法可以用Dask数据帧来做到这一点?我试过,但我只能分别计算聚合列,如下所示:

# group on timestamp (rounded) and url
grouped = df.groupby(['ts', 'url'])

# calculate page views (count rows in each group)
page_views = grouped.size()

# collect a list of referrer strings per group
referrers = grouped['referrer'].apply(list, meta=('referrers', 'f8'))

# count unique visitors (session ids)
visitors = grouped['session_id'].count()

但我似乎无法找到一种很好的方法来生成我需要的组合数据帧。

2 个答案:

答案 0 :(得分:3)

以下确实有效:

gb = df.groupby(['customer', 'url', 'ts'])
gb.apply(lambda d: pd.DataFrame({'views': len(d), 
     'visitiors': d.session_id.count(), 
     'referrers': [d.referer.tolist()]})).reset_index()

(假设访问者应该按照上面的sql是唯一的) 您可能希望定义输出的meta

答案 1 :(得分:2)

这是@ j-bennet打开的link to the github issue,它提供了一个额外的选项。根据这个问题,我们实施了如下聚合:
custom_agg = dd.Aggregation( 'custom_agg', lambda s: s.apply(set), lambda s: s.apply(lambda chunks: list(set(itertools.chain.from_iterable(chunks)))), )
为了与计数结合,代码如下 dfgp = df.groupby(['ID1','ID2']) df2 = dfgp.assign(cnt=dfgp.size()).agg(custom_agg).reset_index()