dask dataframes - 时间序列分区

时间:2018-01-26 18:02:41

标签: pandas dask

我有一个时间序列pandas数据帧,我想按月和年分区。我的想法是得到一个作为索引的日期时间列表,但是在本月的第一天0:00开始时没有发生中断。

monthly_partitons=np.unique(df.index.values.astype('datetime64[M]')).tolist()
da=dd.from_pandas(df, npartitions=1)

如何设置每个月开始的索引?我试过npartitions=len(monthly_partitions)但我意识到这是错误的,因为它可能不会在开始时的日期分区。应该如何确保它在该月的第一天参加竞选?

更新

使用da=da.repartition(freq='1M')重新采样从10分钟数据到1分钟数据的数据,见下文

Dask DataFrame Structure:
Open    High    Low Close   Vol OI  VI  
npartitions=5037050                             
2008-05-04 18:00:00 float64 float64 float64 float64 int64   int64   float64 int32
2008-05-04 18:01:00 ... ... ... ... ... ... ... ...
... ... ... ... ... ... ... ... ...
2017-12-01 16:49:00 ... ... ... ... ... ... ... ...
2017-12-01 16:50:00 ... ... ... ... ... ... ... ...
Dask Name: repartition-merge, 10074101 tasks

更新2:

以下是重现问题的代码

import pandas as pd
import datetime as dt
import dask as dsk
import numpy as np
import dask.dataframe as dd

ts=pd.date_range("2015-01-01 00:00", " 2015-05-01 23:50", freq="10min")
df = pd.DataFrame(np.random.randint(0,100,size=(len(ts),4)), columns=list('ABCD'), index=ts)
ddf=dd.from_pandas(df,npartitions=1)
ddf=ddf.repartition(freq='1M')
ddf

3 个答案:

答案 0 :(得分:2)

假设您的数据框已按时间编入索引,您应该可以使用repartition method来完成此操作。

df = df.repartition(freq='1M')

在MCVE上面编辑

(感谢您添加最小和完整的示例!)

有趣的是,这看起来像是一个bug,无论是在pandas还是dask中。我假设'1M'意味着一个月(就像在pd.date_range中那样)

In [12]: pd.date_range('2017-01-01', '2017-12-15', freq='1M')
Out[12]: 
DatetimeIndex(['2017-01-31', '2017-02-28', '2017-03-31', '2017-04-30',
               '2017-05-31', '2017-06-30', '2017-07-31', '2017-08-31',
               '2017-09-30', '2017-10-31', '2017-11-30'],
              dtype='datetime64[ns]', freq='M')

然而,当传递给pd.Timedelta时,意味着一分钟

In [13]: pd.Timedelta('1M')
Out[13]: Timedelta('0 days 00:01:00')

In [14]: pd.Timedelta('1m')
Out[14]: Timedelta('0 days 00:01:00')

所以它悬而未决,因为它试图制造比你想要的多43200个分区:)

我们应该为此提交错误报告(你有兴趣这样做吗?)。短期解决方法是明确指定部门。

In [17]: divisions = pd.date_range('2015-01-01', '2015-05-01', freq='1M').tolist
    ...: ()
    ...: divisions[0] = ddf.divisions[0]
    ...: divisions[-1] = ddf.divisions[-1]
    ...: ddf.repartition(divisions=divisions)
    ...: 
Out[17]: 
Dask DataFrame Structure:
                         A      B      C      D
npartitions=3                                  
2015-01-01 00:00:00  int64  int64  int64  int64
2015-02-28 00:00:00    ...    ...    ...    ...
2015-03-31 00:00:00    ...    ...    ...    ...
2015-05-01 23:50:00    ...    ...    ...    ...
Dask Name: repartition-merge, 7 tasks

答案 1 :(得分:0)

如果您想在每个月的第一天进行分区,请使用以下命令:

ddf.repartition(freq='MS')

其中MS表示月份开始。更多DateOffset对象的信息可以在pandas docs

中找到

答案 2 :(得分:0)

我不知道为什么会出错,我的数据结构不好

 Filing Date  year             x             y
90042  2014-06-04  2014 -8.239066e+06  4.959789e+06
90043  2011-02-18  2011 -8.209277e+06  4.970069e+06
90044  2000-09-19  2000 -8.228141e+06  4.977555e+06
90045  2010-04-26  2010 -8.226913e+06  4.995798e+06
90046  2012-04-02  2012 -8.230522e+06  4.989788e+06

permits_repartitioned=permits_indexed.repartition(divisions=years)

ValueError:旧部门和新部门的右侧不同

divisions = pd.date_range('2009-01-23', ' 2012-04-02', freq='YS').tolist()
divisions[0] = permits_indexed.divisions[0]
divisions[-1] = permits_indexed.divisions[-1]
permits_repartitioned =permits_indexed.repartition(divisions=divisions)

TypeError:“时间戳记”和“ str”的实例之间不支持“ <”