【问题标题】:Trimming a TimeSeries by timedelta按 timedelta 修剪 TimeSeries
【发布时间】:2014-01-21 08:34:20
【问题描述】:

我正在尝试从 pandas TimeSeries 中删除所有“旧”值,例如所有超过 1 天的值(相对于最新值)。

天真地,我尝试了这样的事情:

from datetime import timedelta
def trim(series):
    return series[series.index.max() - series.index < timedelta(days=1)]

给出错误:

TypeError: ufunc 'subtract' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule 'safe'

很明显,问题出在这个表达式上:series.index.max() - series.index

然后我发现这是可行的:

def trim(series):
    return series[series.index > series.index.max() - timedelta(days=1)]

有人能解释一下为什么后者会起作用,而前者会引发错误吗?

编辑:我使用的是熊猫版本 0.12.0

【问题讨论】:

  • 请显示该系列;这需要 0.12(可能还有 0.13)才能获得适当的时间增量支持
  • @shx2 >.

标签: python pandas time-series timedelta


【解决方案1】:

这是 0.13 中的示例(to_timedelta 在 0.12 中不可用,因此 你必须这样做np.timedelta64(4,'D'))

In [12]: rng = pd.date_range('1/1/2011', periods=10, freq='D')

In [13]: ts = pd.Series(randn(len(rng)), index=rng)

In [14]: ts
Out[14]: 
2011-01-01   -0.348362
2011-01-02    1.782487
2011-01-03    1.146537
2011-01-04   -0.176308
2011-01-05   -0.185240
2011-01-06    1.767135
2011-01-07    0.615911
2011-01-08    2.459799
2011-01-09    0.718081
2011-01-10   -0.520741
Freq: D, dtype: float64

In [15]: x = ts.index.to_series().max()-ts.index.to_series()

In [16]: x
Out[16]: 
2011-01-01   9 days
2011-01-02   8 days
2011-01-03   7 days
2011-01-04   6 days
2011-01-05   5 days
2011-01-06   4 days
2011-01-07   3 days
2011-01-08   2 days
2011-01-09   1 days
2011-01-10   0 days
Freq: D, dtype: timedelta64[ns]

In [17]: x[x>pd.to_timedelta('4 days')]
Out[17]: 
2011-01-01   9 days
2011-01-02   8 days
2011-01-03   7 days
2011-01-04   6 days
2011-01-05   5 days
Freq: D, dtype: timedelta64[ns]

【讨论】:

  • 谢谢。所以我知道使用to_series() 是这里的关键。你能解释一下为什么需要它吗?
  • 索引不是系列,因此它们没有所有相同的方法(在这种情况下,这将适用于应该转换为系列,但这是一种很好的做法)
  • 最初,我没想到索引是系列的。我希望他们是np.array-like。我检查了它们确实来自np.ndarray。这就是我感到惊讶的原因。
  • 它们就像 np.array,但这会改变,不应该依赖
【解决方案2】:

您可以按如下方式使用Truncating and Fancy Indexing

ts.truncate(before='Some Date')

例子:

rng = pd.date_range('1/1/2011', periods=72, freq='D')
ts = pd.Series(randn(len(rng)), index=rng)

ts.truncate(before=(ts.index.max() - dt.timedelta(days=1)).strftime('%m-%d-%Y'))

这应该会截断旧日期之前的所有内容。如果需要,您还可以添加 after 参数以进一步减少它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    • 2013-06-06
    • 2012-08-31
    • 2013-10-13
    • 1970-01-01
    • 2022-12-22
    • 1970-01-01
    相关资源
    最近更新 更多