<pre><code>import numpy as np
import pandas as pd
n = 10
nrows = 33
index = pd.date_range('2000-1-1', periods=nrows, freq='D')
df = pd.DataFrame(np.ones(nrows), index=index)
print(df)
# 0
# 2000-01-01 1
# 2000-01-02 1
# ...
# 2000-02-01 1
# 2000-02-02 1
first = df.index.min()
last = df.index.max() + pd.Timedelta('1D')
secs = int((last-first).total_seconds()//n)
periodsize = '{:d}S'.format(secs)
result = df.resample(periodsize, how='sum')
print('\n{}'.format(result))
assert len(result) == n
</code></pre>
<p>收益率</p>
^{pr2}$
<p><code>0</code>-列中的值表示聚合的行数,因为原始数据帧的值为1。由于33行不能均匀地分为10组,所以4和3的模式基本上是均匀的。在</p>
<hr/>
<p><strong>解释</strong>:考虑这个更简单的数据帧:</p>
<pre><code>n = 2
nrows = 5
index = pd.date_range('2000-1-1', periods=nrows, freq='D')
df = pd.DataFrame(np.ones(nrows), index=index)
# 0
# 2000-01-01 1
# 2000-01-02 1
# 2000-01-03 1
# 2000-01-04 1
# 2000-01-05 1
</code></pre>
<p>使用<code>df.resample('2D', how='sum')</code>会给出错误的组数</p>
<pre><code>In [366]: df.resample('2D', how='sum')
Out[366]:
0
2000-01-01 2
2000-01-03 2
2000-01-05 1
</code></pre>
<p>使用<code>df.resample('3D', how='sum')</code>可以提供正确数量的组,但是
第二组从<code>2000-01-04</code>开始,它不均匀地划分数据帧
分成两个等距分组:</p>
<pre><code>In [367]: df.resample('3D', how='sum')
Out[367]:
0
2000-01-01 3
2000-01-04 2
</code></pre>
<p>为了做得更好,我们需要以比几天更精确的时间分辨率工作。既然<code>Timedelta</code>s有一个<code>total_seconds</code>方法,让我们以秒为单位工作。所以对于上面的例子,期望的频率串应该是</p>
<pre><code>In [374]: df.resample('216000S', how='sum')
Out[374]:
0
2000-01-01 00:00:00 3
2000-01-03 12:00:00 2
</code></pre>
<p>由于5天内有216000*2秒:</p>
<pre><code>In [373]: (pd.Timedelta(days=5) / pd.Timedelta('1S'))/2
Out[373]: 216000.0
</code></pre>
<p>好吧,现在我们需要的是一种推广的方法。我们需要索引中的最短和最长日期:</p>
<pre><code>first = df.index.min()
last = df.index.max() + pd.Timedelta('1D')
</code></pre>
<p>我们多加了一天,因为这会让不同的日子变得不同。在
在上面的例子中,2000-01-05的时间戳之间只有4天
以及2000-01-01</p>
<pre><code>In [377]: (pd.Timestamp('2000-01-05')-pd.Timestamp('2000-01-01')).days
Out[378]: 4
</code></pre>
<p>但是,正如我们在示例中看到的,DataFrame有5行代表5
天。所以我们需要多加一天。在</p>
<p>现在,我们可以计算出每个等间距组的正确秒数:</p>
<pre><code>secs = int((last-first).total_seconds()//n)
</code></pre>