Dask DataFrame:对具有多行的groupby对象进行重新取样

时间:2015-11-26 18:28:49

标签: python pandas dataframe dask castra

我有从Castra创建的以下dask数据框:

import dask.dataframe as dd

df = dd.from_castra('data.castra', columns=['user_id','ts','text'])

产量:

                      user_id / ts                  / text
ts
2015-08-08 01:10:00   9235      2015-08-08 01:10:00   a
2015-08-08 02:20:00   2353      2015-08-08 02:20:00   b
2015-08-08 02:20:00   9235      2015-08-08 02:20:00   c
2015-08-08 04:10:00   9235      2015-08-08 04:10:00   d
2015-08-08 08:10:00   2353      2015-08-08 08:10:00   e

我要做的是:

  1. user_idts
  2. 分组
  3. 在3小时内重新取样
  4. 在重新采样步骤中,任何合并的行都应该连接文本
  5. 示例输出:

                                    text
    user_id   ts
    9235      2015-08-08 00:00:00   ac
              2015-08-08 03:00:00   d
    2353      2015-08-08 00:00:00   b
              2015-08-08 06:00:00   e
    

    我尝试了以下内容:

    df.groupby(['user_id','ts'])['text'].sum().resample('3H', how='sum').compute()
    

    并收到以下错误:

    TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex
    

    我尝试在管道中传递set_index('ts'),但它似乎不是Series的属性。

    关于如何实现这一目标的任何想法?

    TL; DR

    如果它使问题更容易,我也能够改变我创建的Castra DB的格式。我目前的实施主要来自this伟大的帖子。

    我按如下方式设置索引(在to_df()函数中):

    df.set_index('ts',drop=False,inplace=True)
    

    并且:

      with BZ2File(os.path.join(S.DATA_DIR,filename)) as f:
         batches = partition_all(batch_size, f)
         df, frames = peek(map(self.to_df, batches))
         castra = Castra(S.CASTRA, template=df, categories=categories)
         castra.extend_sequence(frames, freq='3h')
    

    以下是生成的dtypes:

    ts                datetime64[ns]
    text                      object
    user_id                  float64
    

2 个答案:

答案 0 :(得分:2)

如果我们可以假设每个user-id组都可以放入内存中,那么我建议使用dask.dataframe来执行外部groupby,然后使用pandas在每个组中执行操作,如下所示。< / p>

def per_group(blk):
    return blk.groupby('ts').text.resample('3H', how='sum')

df.groupby('user_id').apply(per_group, columns=['ts', 'text']).compute()

这将两件难事分解为两个不同的项目

  1. 将所有用户ID混合到正确的组中由dask.dataframe处理
  2. 在每个组中进行复杂的日期时间重采样由pandas明确处理。
  3. 理想情况下,dask.dataframe会自动为您编写每组功能。目前,dask.dataframe不能智能地处理多索引,或者在多列groupbys之上重新采样,因此自动解决方案尚未可用。尽管如此,在使用dask.dataframe相应地准备组的同时,很有可能回退到用于每块计算的pandas。

答案 1 :(得分:0)

尝试将您的索引转换为DatetimeIndex,如下所示:

import datetime
# ...
df.index = dd.DatetimeIndex(df.index.map(lambda x: datetime.datetime.strptime(x, '%Y-%m-%d %H:%M:%S')))
# ...