Python Dask数据帧:在具有多行的groupby对象上重新采样
我从Castra创建了以下dask数据帧: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-
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
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会自动为您编写每组函数。目前,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')
,以防止出现警告。