我有一个时间序列熊猫数据帧,我想按月份和年份进行分区。 我的想法是获取一个日期时间列表,该列表将用作索引,但中断不会在每月第一天的 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
假设数据帧已按时间编制索引,您应该能够使用重新分区方法来完成此操作。
df = df.repartition(freq='1M')
在上面的MCVE之后编辑
(感谢您添加最小和完整的示例!
有趣的是,这看起来像一个错误,无论是在熊猫还是 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
如果您想在每个月的第一天进行分区,请使用以下命令:
ddf.repartition(freq='MS')
其中MS
表示月份开始。 有关更多DateOffset
对象的信息可以在 pandas 文档中找到