pd.period_range中freq ='1H'和freq ='60T'之间的差异逻辑

时间:2016-07-09 15:35:37

标签: pandas time-series

我想了解之间的区别:

rng = pd.period_range('2016-01-01 12:15', freq = '60T', periods = 10)
rng

产生

PeriodIndex(['2016-01-01 12:15', '2016-01-01 13:15', '2016-01-01 14:15',
             '2016-01-01 15:15', '2016-01-01 16:15', '2016-01-01 17:15',
             '2016-01-01 18:15', '2016-01-01 19:15', '2016-01-01 20:15',
             '2016-01-01 21:15'],
            dtype='int64', freq='60T')

rng = pd.period_range('2016-01-01 12:15', freq = '1H', periods = 10)
rng

产生

PeriodIndex(['2016-01-01 12:00', '2016-01-01 13:00', '2016-01-01 14:00',
             '2016-01-01 15:00', '2016-01-01 16:00', '2016-01-01 17:00',
             '2016-01-01 18:00', '2016-01-01 19:00', '2016-01-01 20:00',
             '2016-01-01 21:00'],
            dtype='int64', freq='H')

这是与熊猫时间序列功能的一致差异吗?如果是这样,理由是什么,我在哪里可以找到文档中描述的内容?

1 个答案:

答案 0 :(得分:2)

文档中的API reference似乎缺少PeriodPeriodIndex(自v0.18.1起) - {{3}中有对它们的引用}和Time Series / Date functionality > Time Span Representation部分。所以为了好玩,我决定深入研究源代码,弄清楚它们是如何工作的。这是我发现的。

Period

Period个对象代表常规时间间隔。在内部,它们由

组成
  • 整数ordinal,用于编码间隔的起点,
  • 一个对象freq - 类型为DateOffset的某个子类 - 表示持续时间(实质上)为一对整数乘数n和一个字符串name基本时间单位 - 秒,分钟,小时等等或更复杂的时间单位,如工作日或营业时间(请参阅Internals > Indexing基本可能性,here他们的别名是什么;您可以还herecombine them,...)

要将起始点从整数ordinal转换为更易于阅读的内容,请将基本时间单位(freq.name)乘以所述整数,并将其添加到1970-01-01 00:00:00(at至少在我的系统中:根据anchor them,它可能取决于频率:-S)。

import pandas as pd

p1 = pd.Period('1970-01-01 00:00', 'H')
print(p1.ordinal)     # => 0
print(p1.freq.n)      # => 1
print(p1.freq.name)   # => H
print(repr(p1))       # => Period('1970-01-01 00:00', 'H')

p2 = pd.Period('1970-01-01 02:00', 'H')
print(p2.ordinal)     # => 2
print(p2.freq.n)      # => 1
print(p2.freq.name)   # => H
print(repr(p2))       # => Period('1970-01-01 02:00', 'H')

p3 = pd.Period('1970-01-01 00:00', 'M')
print(p3.ordinal)     # => 0
print(p3.freq.n)      # => 1
print(p3.freq.name)   # => M
print(repr(p3))       # => Period('1970-01', 'M')

p4 = pd.Period('1970-03-01 00:00', 'M')
print(p4.ordinal)     # => 2
print(p4.freq.n)      # => 1
print(p4.freq.name)   # => M
print(repr(p4))       # => Period('1970-03', 'M')

请注意,该解决方案与freq.name相关联,且与freq.n无关。

p5 = pd.Period('1970-03-01 00:00', '6M')
print(p5.ordinal)     # => 2
print(p5.freq.n)      # => 6
print(p5.freq.name)   # => M
print(repr(p5))       # => Period('1970-03', '6M')

这个整数的内部表示解释了为什么Period不能有任意起点。创建一个{<1}}对象,其起始点不是 on offset ,将后者移向过去,直到最接近 on offset 时间点。

Period

p6 = pd.Period('1970-03-05 23:59', 'M') print(p6.ordinal) # => 3 print(p6.freq.n) # => 1 print(p6.freq.name) # => M print(repr(p6)) # => Period('1970-03', 'M') print(p4 == p6) # => True

PeriodIndex es作为PeriodIndex s的数组,具有公共Period。实际上,它们存储为一对:

  • 一个不可变的整数ndarray - freq s的集合,如果你想 - 和
  • 一个ordinal对象。

freq会返回其中一个。

pd.period_range()

访问rng = pd.period_range('2016-01-01 12:00', freq='1H', periods=5) print(type(rng)) # => <class 'pandas.tseries.period.PeriodIndex'> print(rng.values) # => [403236 403237 403238 403239 403240] print(rng.freq.n) # => 1 print(rng.freq.name) # => H 的成员会返回PeriodIndex个对象。

Period

代码在哪里?

print(type(rng[0])) # => <class 'pandas._period.Period'> print(repr(rng[0])) # => Period('2016-01-01 12:00', 'H') 类在this issue(Cython!)中定义。

Period及其子类位于pandas/src/period.pyx

DateOffset位于pandas/tseries/offsets.py