Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Dask数据帧:在具有多行的groupby对象上重新采样_Python_Pandas_Dataframe_Dask_Castra - Fatal编程技术网

Python Dask数据帧:在具有多行的groupby对象上重新采样

Python Dask数据帧:在具有多行的groupby对象上重新采样,python,pandas,dataframe,dask,castra,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-

我从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
我想做的是:

                                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
  • user\u id
    ts
  • 在3小时内重新取样
  • 在重采样步骤中,任何合并行都应连接文本
  • 示例输出:

                                    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\u index('ts')
    ,但它似乎不是
    Series
    的属性

    关于如何实现这一点有什么想法吗

    TL;DR

    如果这使问题变得更容易,我还可以更改我创建的Castra DB的格式。我目前的实现主要是从great post中获取的

    我将索引(在
    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')
    
    以下是生成的数据类型:

    ts                datetime64[ns]
    text                      object
    user_id                  float64
    

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

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

    如果我们可以假设每个
    用户id
    组都可以放入内存,那么我建议使用dask.dataframe来执行外部groupby,然后使用pandas来执行每个组内的操作,如下所示

    def per_group(blk):
        return blk.groupby('ts').text.resample('3H', how='sum')
    
    df.groupby('user_id').apply(per_group, columns=['ts', 'text']).compute()
    
    这将两个困难的事情分离到两个不同的项目中

  • dask.dataframe处理将所有用户ID混合到正确的组中
  • 在每个组中执行复杂的日期时间重采样由pandas显式处理

  • 理想情况下,dask.dataframe会自动为您编写每组函数。目前,dask.dataframe不能智能地处理多个索引,或者在多列groupbys之上重新采样,因此自动解决方案还不可用。尽管如此,在仍然使用dask.dataframe来相应地准备组的情况下,仍有可能回到pandas进行每块计算。

    感谢您提供了出色的解决方案。使用
    apply
    是否是访问dask中不存在的功能的推荐方法(假设块可以放入内存)?这将大大有助于绕过dask数据帧的当前限制!一般来说,是的。groupby apply方法将始终有效,只是速度不如纯dask.dataframe解决方案。Dask.dataframe永远无法达到熊猫的全部宽度,因此逃生舱口非常重要。您在这个问题上已经帮了我很多忙,但您能否告诉我生成的对象类型是什么?当我打印
    type(df)
    时,它会给我
    dask.dataframe.core.dataframe
    ,但我无法运行
    。\u castra
    或获取
    等。行为是否发生了变化?让我知道我是否应该将此作为新问题发布。再次感谢!一切都会好起来的。您可能需要检查
    列=
    kwarg是否正确。我主要是猜测结果列是什么。在
    apply
    中添加
    ,meta=('int32')
    ,以防止出现警告。