如何理解熊猫重采样方法中的封闭和标签参数?
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
而不是重新采样以上是关于如何理解熊猫重采样方法中的封闭和标签参数?的主要内容,如果未能解决你的问题,请参考以下文章