python - 我怎样才能近似 Pandas 时间序列的周期

标签 python pandas

有没有办法在 pandas 中近似时间序列的周期性?对于 R,xts对象有一个名为 periodicity 的方法正是为了这个目的。有没有实现的方法来做到这一点?

例如,我们能否从未指定频率的时间序列中推断出频率?

import pandas.io.data as web
aapl = web.get_data_yahoo("AAPL")

<class 'pandas.tseries.index.DatetimeIndex'>
[2010-01-04 00:00:00, ..., 2013-12-19 00:00:00]
Length: 999, Freq: None, Timezone: None

这个系列的频率可以合理地近似为每天一次。

更新:

我认为显示 R 实现周期性方法的源代码可能会有所帮助。

function (x, ...) 
{
    if (timeBased(x) || !is.xts(x)) 
        x <- try.xts(x, error = "'x' needs to be timeBased or xtsible")
    p <- median(diff(.index(x)))
    if (is.na(p)) 
        stop("can not calculate periodicity of 1 observation")
    units <- "days"
    scale <- "yearly"
    label <- "year"
    if (p < 60) {
        units <- "secs"
        scale <- "seconds"
        label <- "second"
    }
    else if (p < 3600) {
        units <- "mins"
        scale <- "minute"
        label <- "minute"
        p <- p/60L
    }
    else if (p < 86400) {
        units <- "hours"
        scale <- "hourly"
        label <- "hour"
    }
    else if (p == 86400) {
        scale <- "daily"
        label <- "day"
    }
    else if (p <= 604800) {
        scale <- "weekly"
        label <- "week"
    }
    else if (p <= 2678400) {
        scale <- "monthly"
        label <- "month"
    }
    else if (p <= 7948800) {
        scale <- "quarterly"
        label <- "quarter"
    }
    structure(list(difftime = structure(p, units = units, class = "difftime"), 
        frequency = p, start = start(x), end = end(x), units = units, 
        scale = scale, label = label), class = "periodicity")
}

我认为这一行是关键,我不太明白 p <- median(diff(.index(x)))

最佳答案

这个时间序列跳过了周末(和节假日),所以它确实没有每天的频率开始。您可以使用 asfreq 将其上采样为每日频率的时间序列,但是:

aapl = aapl.asfreq('D', method='ffill')

这样做会将最后观察到的值向前传播到具有缺失值的日期。

请注意,Pandas 也有一个工作日频率,因此也可以使用以下方法将上采样到工作日:

aapl = aapl.asfreq('B', method='ffill')

如果您希望自动推断以天为单位的中位数频率的过程,那么您可以这样做:

import pandas as pd
import numpy as np
import pandas.io.data as web
aapl = web.get_data_yahoo("AAPL")
f  = np.median(np.diff(aapl.index.values))
days = f.astype('timedelta64[D]').item().days
aapl = aapl.asfreq('{}D'.format(days), method='ffill')
print(aapl)

此代码需要测试,但它可能接近您发布的 R 代码:

import pandas as pd
import numpy as np
import pandas.io.data as web

def infer_freq(ts):
    med  = np.median(np.diff(ts.index.values))
    seconds = int(med.astype('timedelta64[s]').item().total_seconds())
    if seconds < 60:
        freq = '{}s'.format(seconds)
    elif seconds < 3600:
        freq = '{}T'.format(seconds//60)
    elif seconds < 86400:
        freq = '{}H'.format(seconds//3600)
    elif seconds < 604800:
        freq = '{}D'.format(seconds//86400)
    elif seconds < 2678400:
        freq = '{}W'.format(seconds//604800)
    elif seconds < 7948800:
        freq = '{}M'.format(seconds//2678400)
    else:
        freq = '{}Q'.format(seconds//7948800)
    return ts.asfreq(freq, method='ffill')

aapl = web.get_data_yahoo("AAPL")
print(infer_freq(aapl))

关于python - 我怎样才能近似 Pandas 时间序列的周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20711838/

相关文章:

python - 安装 pip 时出现 anaconda2 错误

Python pandas 将 Excel 文件中的多个标题转换为列

python pandas如何按 block 读取csv文件

python - 合并年和周列以在 python 中创建日期时间和排序

python - 在 Python/pandas 中自动生成组合 DataFrame

python - 消息 : ConnectionError(ProtocolError ('Connection aborted.' , 错误 (2, 'No such file or directory' )),)

python - 如何创建一个预提交 Hook ,在推送到服务器之前跟踪 Django 代码中的错误

python - spaCy 和 Docker : can't "dockerize" Flask app that uses spaCy modules

python - 读取大型文本文件时即时计算 md5

python - 在 Python (Pandas/Numpy) 中,如何使用条件和特定 block 大小对 df 进行子集化?