如何理解熊猫重采样方法中的封闭和标签参数?

Posted

技术标签:

【中文标题】如何理解熊猫重采样方法中的封闭和标签参数?【英文标题】:how to understand closed and label arguments in pandas resample method? 【发布时间】:2018-06-28 15:46:09 【问题描述】:

基于此处的 pandas 文档:Docs

还有例子:

>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-01-01 00:00:00    0
2000-01-01 00:01:00    1
2000-01-01 00:02:00    2
2000-01-01 00:03:00    3
2000-01-01 00:04:00    4
2000-01-01 00:05:00    5
2000-01-01 00:06:00    6
2000-01-01 00:07:00    7
2000-01-01 00:08:00    8
Freq: T, dtype: int64

重采样后:

>>> series.resample('3T', label='right', closed='right').sum()
2000-01-01 00:00:00     0
2000-01-01 00:03:00     6
2000-01-01 00:06:00    15
2000-01-01 00:09:00    15

在我看来,重新采样后的 bin 应该是这样的:

=========bin 01=========
2000-01-01 00:00:00    0
2000-01-01 00:01:00    1
2000-01-01 00:02:00    2

=========bin 02=========
2000-01-01 00:03:00    3
2000-01-01 00:04:00    4
2000-01-01 00:05:00    5

=========bin 03=========
2000-01-01 00:06:00    6
2000-01-01 00:07:00    7
2000-01-01 00:08:00    8

我在这一步上正确吗??

所以.sum之后我觉得应该是这样的:

2000-01-01 00:02:00     3
2000-01-01 00:05:00    12
2000-01-01 00:08:00    21

我只是不明白它是怎么出来的:

2000-01-01 00:00:00 0

(因为在这种情况下,label='right', 2000-01-01 00:00:00 不能是任何 bin 的任何右边缘)。

2000-01-01 00:09:00 15

(原始系列中甚至不存在标签 2000-01-01 00:09:00。

【问题讨论】:

不,closed='right' 表示它是另一种方式。 @JohnE 感谢您的回复。我理解 closed=right 意味着右边缘包含在间隔中。你能告诉我series.resample('3T', label='right', closed='right')重新采样后的3个箱子是什么样子吗?我认为2000-01-01 00:00:00 0 不应该出现在.sum 之后。 我以为我已经在回答中解决了这个问题,但我会尽量让它更清楚 我认为这是因为您正在使用“3T”重新采样,这表示每个样本的时间为 3 分钟,而不是 3 行 【参考方案1】:

根据 JohnE 的回答,我整理了一个有用的信息图,可以一劳永逸地解决这个问题:

【讨论】:

【参考方案2】:

重采样是通过首先生成一个栅格来执行的,该栅格是一系列瞬间(不是周期、间隔、持续时间),并且它独立于“标签”和“闭合”参数来完成,这一点很重要。它仅使用“freq”参数和“loffset”。在您的情况下,系统将生成以下栅格:

2000-01-01 00:00:00
2000-01-01 00:03:00
2000-01-01 00:06:00
2000-01-01 00:09:00

请再次注意,目前没有区间或周期方面的解释。你可以使用'loffset'来移动它。

然后系统将使用'close'参数在两个选项中进行选择:

(开始,结束]

[开始,结束)

这里的 start 和 end 是栅格中两个相邻的时间戳。 'label' 参数用于选择是否使用 start 或 end 作为间隔的代表。

在您的示例中,如果您选择 closed='right' 那么您将获得以下间隔:

( previous_interval , 2000-01-01 00:00:00] - 0
(2000-01-01 00:00:00, 2000-01-01 00:03:00] - 1,2,3
(2000-01-01 00:03:00, 2000-01-01 00:06:00] - 1,2,3
(2000-01-01 00:06:00, 2000-01-01 00:09:00] - 4,5,6
(2000-01-01 00:09:00, next_interval ] - 7,8

请注意,在您聚合这些间隔内的值后,结果会根据“标签”参数显示为两个版本,也就是说,相同的间隔是否由其左侧或右侧时间戳表示。

【讨论】:

【参考方案3】:

简答:如果你使用closed='left'loffset='2T',那么你会得到你所期望的:

series.resample('3T', label='left', closed='left', loffset='2T').sum()

2000-01-01 00:02:00     3
2000-01-01 00:05:00    12
2000-01-01 00:08:00    21

长答案:(或者为什么你得到的结果是正确的,考虑到你使用的参数)这可能从文档中不清楚,但在这个设置中打开和关闭是关于严格与非- 严格的不等式(例如< vs <=)。

一个例子应该可以清楚地说明这一点。使用示例中的内部间隔,这与更改 closed 的值不同:

closed='right' =>  ( 3:00, 6:00 ]  or  3:00 <  x <= 6:00
closed='left'  =>  [ 3:00, 6:00 )  or  3:00 <= x <  6:00

您可以在许多地方找到区间符号(括号与括号)的解释,例如这里: https://en.wikipedia.org/wiki/Interval_(mathematics)

label 参数仅控制显示左侧 (3:00) 还是右侧 (6:00),而不影响结果本身。

另请注意,您可以使用loffset 参数(应作为时间增量输入)更改间隔的起点。

回到示例,我们只将标签从“右”更改为“左”:

series.resample('3T', label='right', closed='right').sum()

2000-01-01 00:00:00     0
2000-01-01 00:03:00     6
2000-01-01 00:06:00    15
2000-01-01 00:09:00    15

series.resample('3T', label='left', closed='right').sum()

1999-12-31 23:57:00     0
2000-01-01 00:00:00     6
2000-01-01 00:03:00    15
2000-01-01 00:06:00    15

如您所见,结果是一样的,只是索引标签发生了变化。 Pandas 只允许您显示右侧或左侧标签,但如果它显示 both,那么它看起来像这样(下面我使用标准索引符号,其中左侧的 ( 表示打开并且右侧]表示关闭):

( 1999-12-31 23:57:00, 2000-01-01 00:00:00 ]   0   # = 0
( 2000-01-01 00:00:00, 2000-01-01 00:03:00 ]   6   # = 1+2+3
( 2000-01-01 00:03:00, 2000-01-01 00:06:00 ]  15   # = 4+5+6
( 2000-01-01 00:06:00, 2000-01-01 00:09:00 ]  15   # =   7+8

请注意,第一个 bin (23:57:00,00:00:00] 不为空,只是它包含一行并且该行中的值为零。如果将“sum”更改为'count' 这变得更加明显:

series.resample('3T', label='left', closed='right').count()

1999-12-31 23:57:00    1
2000-01-01 00:00:00    3
2000-01-01 00:03:00    3
2000-01-01 00:06:00    2

【讨论】:

您知道如何将重新采样日期作为新列分配给原始数据框吗?例如,300*24 行,日期列来自%Y-%m-%d %H(每小时 300 天)。我需要每 7 天 groupby 他们,最后一天锚到今天,以 7* 24 回滚。因为某些原因我不能使用 resample.agg ,所以我需要将重新采样的日期列设置回原始数据框 @Mithril 这是一个有趣的问题,您可能想发布一个新问题以获得一个好的和具体的答案。在我的脑海中,我可以看到 2 种替代方法:(1) 使用 merge_asof 合并回原始数据,或者 (2) 使用 interpolate 而不是重新采样

以上是关于如何理解熊猫重采样方法中的封闭和标签参数?的主要内容,如果未能解决你的问题,请参考以下文章

基于列标准的熊猫数据框重采样

熊猫结合了滚动和重采样

熊猫时间序列重采样和插值一起

重采样后合并熊猫数据帧

带有熊猫重采样的额外箱

pandas的resample重采样