【问题标题】:How to filter a pandas series with a datetime index on the quarter and year如何过滤具有季度和年份日期时间索引的熊猫系列
【发布时间】:2016-11-29 04:49:20
【问题描述】:

我有一个名为“scores”的系列,带有一个日期时间索引。

我希望通过 quarteryear 对其进行子集化
伪代码:series.loc['q2 of 2013']

目前的尝试:
s.dt.quarter

AttributeError: 只能使用带有 datetimelike 值的 .dt 访问器

s.index.dt.quarter

AttributeError: 'DatetimeIndex' 对象没有属性 'dt'

这很有效(灵感来自this answer),但我不敢相信这是在 Pandas 中执行此操作的正确方法:

d = pd.DataFrame(s)
d['date'] = pd.to_datetime(d.index)
d.loc[(d['date'].dt.quarter == 2) & (d['date'].dt.year == 2013)]['scores']

我希望有一种方法可以做到这一点,而无需转换为数据集,将索引强制转换为日期时间,然后从中获取系列。

我缺少什么,在 Pandas 系列中执行此操作的优雅方式是什么?

【问题讨论】:

  • 如果索引是日期时间s.index.quarter,这将起作用。
  • 你想要一个可以在特定年份和季度获得的函数吗?
  • IIUC 你需要scores.ix[scores.index.quarter==2].
  • @shivsn 有正确的答案,我很震惊我没想过放弃dt 的事情。

标签: python datetime pandas datetimeindex


【解决方案1】:
import numpy as np
import pandas as pd

index = pd.date_range('2013-01-01', freq='M', periods=12)
s = pd.Series(np.random.rand(12), index=index)
print(s)

# 2013-01-31    0.820672
# 2013-02-28    0.994890
# 2013-03-31    0.928376
# 2013-04-30    0.848532
# 2013-05-31    0.122263
# 2013-06-30    0.305741
# 2013-07-31    0.088432
# 2013-08-31    0.647288
# 2013-09-30    0.640308
# 2013-10-31    0.737139
# 2013-11-30    0.233656
# 2013-12-31    0.245214
# Freq: M, dtype: float64

d = pd.Series(s.index, index=s.index)
quarter = d.dt.quarter.astype(str) + 'Q' + d.dt.year.astype(str)
print(quarter)

# 2013-01-31    1Q2013
# 2013-02-28    1Q2013
# 2013-03-31    1Q2013
# 2013-04-30    2Q2013
# 2013-05-31    2Q2013
# 2013-06-30    2Q2013
# 2013-07-31    3Q2013
# 2013-08-31    3Q2013
# 2013-09-30    3Q2013
# 2013-10-31    4Q2013
# 2013-11-30    4Q2013
# 2013-12-31    4Q2013
# Freq: M, dtype: object

print(s[quarter == '1Q2013'])

# 2013-01-31    0.124398
# 2013-02-28    0.052828
# 2013-03-31    0.126374
# Freq: M, dtype: float64

如果您不想创建一个包含每个季度标签的新系列(例如,如果您只设置一次子集),您甚至可以这样做

print(s[(s.index.quarter == 1) & (s.index.year == 2013)])

# 2013-01-31    0.124398
# 2013-02-28    0.052828
# 2013-03-31    0.126374
# Freq: M, dtype: float64

【讨论】:

    【解决方案2】:

    如果您知道年份和季度,比如 2013 年第二季度,那么您可以这样做:

    s['2013-04':'2013-06']
    

    把它包装成一个函数:

    qmap = pd.DataFrame([
            ('01', '03'), ('04', '06'), ('07', '09'), ('10', '12')
        ], list('1234'), list('se')).T
    
    def get_quarter(df, year, quarter):
        s, e = qmap[str(quarter)]
        y = str(year)
        s = y + '-' + s
        e = y + '-' + e
        return df[s:e]
    

    然后调用它:

    get_quarter(s, 2013, 2)
    

    假设s 是:

    s = pd.Series(range(32), pd.date_range('2011-01-01', periods=32, freq='Q'))
    

    然后我得到:

    2013-03-31    8
    Freq: Q-DEC, dtype: int64
    

    【讨论】:

      【解决方案3】:

      假设你有一个这样的数据框:

      sa
      Out[28]: 
                   0
      1970-01-31   1
      1970-02-28   2
      1970-03-31   3
      1970-04-30   4
      1970-05-31   5
      1970-06-30   6
      1970-07-31   7
      1970-08-31   8
      1970-09-30   9
      1970-10-31  10
      1970-11-30  11
      1970-12-31  12
      

      如果索引是日期时间,那么您可以获得季度为sa.index.quarter

      sa.index.quarter
      Out[30]: array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-02
        • 1970-01-01
        • 2019-02-19
        • 1970-01-01
        • 2020-08-20
        • 2021-12-29
        • 2019-02-25
        • 2022-11-16
        相关资源
        最近更新 更多