【问题标题】:Python Pandas: Split a TimeSerie per month or weekPython Pandas:每月或每周拆分一个 TimeSerie
【发布时间】:2017-05-28 06:18:21
【问题描述】:

我有一个跨越几年的 Timeserie,格式如下:

              timestamp open    high    low    close    volume
0   2009-01-02 05:00:00 900.00  906.75  898.00  904.75  15673.0
1   2009-01-02 05:30:00 904.75  907.75  903.75  905.50  4600.0
2   2009-01-02 06:00:00 905.50  907.25  904.50  904.50  3472.0
3   2009-01-02 06:30:00 904.50  905.00  903.25  904.75  6074.0
4   2009-01-02 07:00:00 904.75  905.50  897.00  898.25  12538.0

将该数据帧拆分为多个数据帧的 1 周或 1 个月数据的最简单方法是什么?77

编辑:例如,包含 1 年数据的数据帧将被拆分为 52 个包含一周数据的数据帧,并作为 52 个数据帧的列表返回

(数据可以用下面的公式重构)

import pandas as pd
from pandas import Timestamp
dikt={'close': {0: 904.75, 1: 905.5, 2: 904.5, 3: 904.75, 4: 898.25}, 'low': {0: 898.0, 1: 903.75, 2: 904.5, 3: 903.25, 4: 897.0}, 'open': {0: 900.0, 1: 904.75, 2: 905.5, 3: 904.5, 4: 904.75}, 'high': {0: 906.75, 1: 907.75, 2: 907.25, 3: 905.0, 4: 905.5}, 'volume': {0: 15673.0, 1: 4600.0, 2: 3472.0, 3: 6074.0, 4: 12538.0}, 'timestamp': {0: Timestamp('2009-01-02 05:00:00'), 1: Timestamp('2009-01-02 05:30:00'), 2: Timestamp('2009-01-02 06:00:00'), 3: Timestamp('2009-01-02 06:30:00'), 4: Timestamp('2009-01-02 07:00:00')}}
pd.DataFrame(dikt, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])

【问题讨论】:

  • 当您说“拆分”时,您希望如何交付拆分?你想让它们在字典里吗?在另一个数据框中?您应该花时间指定您希望看到的内容。
  • @piRSquared 以包含 1 年数据的数据帧为例,将被拆分为每周 52 个数据帧,并以 52 个数据帧的列表形式返回。

标签: python pandas time-series


【解决方案1】:

pd.TimeGrouper 已弃用并将被删除,您可以改用pd.Grouper

weeks = [g for n, g in df.groupby(pd.Grouper(key='timestamp',freq='W'))]
months = [g for n, g in df.groupby(pd.Grouper(key='timestamp',freq='M'))]

这样您还可以避免将timestamp 设置为索引


另外,如果您的时间戳是多索引的一部分,您可以使用level 参数(例如pd.Grouper(level='timestamp', freq='W'))来引用它。比@jtromans 更重要。

【讨论】:

  • 如果您对时间戳使用多索引,您可以参考适当的级别 pd.Grouper(level='TM_ID',freq='M') 在我的情况下 TM_ID 是适当的日期时间表示。
【解决方案2】:

使用 groupbypd.TimeGrouper 并列出推导

weeks = [g for n, g in df.set_index('timestamp').groupby(pd.TimeGrouper('W'))]
months = [g for n, g in df.set_index('timestamp').groupby(pd.TimeGrouper('M'))]

如果需要,您可以重置索引

weeks = [g.reset_index()
         for n, g in df.set_index('timestamp').groupby(pd.TimeGrouper('W'))]
months = [g.reset_index()
          for n, g in df.set_index('timestamp').groupby(pd.TimeGrouper('M'))]

dict

weeks = {n: g.reset_index()
         for n, g in df.set_index('timestamp').groupby(pd.TimeGrouper('W'))}
months = {n: g.reset_index()
          for n, g in df.set_index('timestamp').groupby(pd.TimeGrouper('M'))}

【讨论】:

  • 绝妙的答案,当机立断!非常感谢。我知道有一种方法可以使它非常简洁。我一直试图更好地理解 groupby 方法,但我遇到的一个困难是无法检查 groupBy 对象本身的内部......为什么会这样?或者有没有办法真正做到这一点?
  • groupby 对象是帮助进行这些分组活动的设备。它包含有关在何处拆分数据帧、每个组的唯一名称和手动方法的信息。它本身并不是一个真正的数据结构(我相信您可以将其解释为一个)。通过像我一样遍历它,groupby 类告诉它为每个名称生成组的名称和数据帧的切片。这就是为什么我问你想要它的原因。
  • 在哪里可以找到有关 groupby 对象的“手动方法”的文档?文档页面没有列出它们:pandas.pydata.org/pandas-docs/stable/generated/…
  • 另外,你能解释一下g for n, g in ...这个表达式吗?应用于 groupby 对象的 for 循环是否返回了 2 个元素?
【解决方案3】:

我会为此使用 group by,假设 df 存储数据

df = df.set_index('timestamp')
df.groupby(pd.TimeGrouper(freq='D'))

然后生成的组将包含您正在寻找的所有数据框。 这里引用了这个答案

How to group DataFrame by a period of time?

【讨论】:

  • 右括号问题?
【解决方案4】:

timestamp 列转换为DateTimeIndex,然后您可以通过多种方式对其进行切片。

【讨论】:

    【解决方案5】:

    TimeGrouper 的概念是正确的,但语法似乎不适用于 pandas 的最新版本。这是我在Pandas 1.1.3上的工作代码

    df_Time = df.copy()
    df_Time = df_Time.groupby(pd.Grouper(key='time', freq='M')).agg({
        'polarity': 'mean',
    })
    

    pd.Grouper(key='time', freq='M') 是您所需要的。 key 是存在时间/时间戳的列,freq 可以采用非常有用的选项的多个值。偏移别名(频率选项)的完整列表可以在here找到。

    主要是

    B: business day frequency
    C: custom business day frequency
    D: calendar day frequency
    W: weekly frequency
    M: month end frequency
    

    【讨论】:

      猜你喜欢
      • 2013-12-24
      • 1970-01-01
      • 1970-01-01
      • 2011-05-30
      • 2021-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多