【问题标题】:Python pandas - resample every 2nd row rather than every 2nd business dayPython pandas - 每第二行而不是每第二个工作日重新采样
【发布时间】:2018-12-06 10:09:21
【问题描述】:

我正在处理股票价格数据,并希望 resample() 每第二行而不是每第二个工作日返回一次 (resample('2B'))。障碍是任何在工作日登陆的假期。见下文,MLK 日是 2018 年 1 月 15 日星期一:

import pandas as pd

data = '''\
date,price
2018-01-08,88.28
2018-01-09,88.22
2018-01-10,87.82
2018-01-11,88.08
2018-01-12,89.6
2018-01-16,88.35
2018-01-17,90.14
2018-01-18,90.1
2018-01-19,90.0
2018-01-22,91.61
2018-01-23,91.9
2018-01-24,91.82
2018-01-25,92.33
2018-01-26,94.06'''

fileobj = pd.compat.StringIO(data)
df = pd.read_csv(fileobj, parse_dates=['date'], index_col=[0])

df_resample = df.resample('2B').min()
print(df_resample)

输出:

            price
2018-01-08  88.22
2018-01-10  87.82
2018-01-12  89.60
2018-01-16  88.35
2018-01-18  90.00
2018-01-22  91.61
2018-01-24  91.82
2018-01-26  94.06

我希望重新采样从 1/12 跳到 1/17。我知道我可以使用df['price'].loc[::2] 传递df.resample('2B').last(),但我还需要使用min()max()sum()

谢谢。

预期输出:

【问题讨论】:

  • df.loc[::2] 是我的第一个想法,你能解释一下为什么这不适用于这个数据集吗? minmax 等如果你切片框架应该都可以正常工作
  • 我的想法是以某种方式重新定义工作日。也许是这样的:stackoverflow.com/questions/33094297/…
  • Haleemur - 你将如何使用.loc[::2] 返回最少 2 天(每 2 行)?
  • @MJS,感谢您使用示例数据更新问题,现在您想要实现的目标更清楚了。顺便说一句,在回复 cmets 时,您可以使用 @username 提及您正在寻址的用户。否则,用户不会收到评论活动通知

标签: python pandas resampling datetimeindex


【解决方案1】:

对于一个稳定的解决方案,我会考虑以某种方式重新定义 B-days。

但如果你重置索引,你可以使用索引号和 groupby:

df = df.reset_index()
df_resample = df.groupby(df.index // 2).min()
print(df_resample)

返回:

        date  price
0 2018-01-08  88.22
1 2018-01-10  87.82
2 2018-01-12  88.35
3 2018-01-17  90.10
4 2018-01-19  90.00
5 2018-01-23  91.82
6 2018-01-25  92.33

或者你可以这样做:

g = np.arange(len(df))// 2
df_resample = df.groupby(g).agg(['last','min','max','sum'])
df_resample.insert(0, 'Date', df.index[1::2])

print(df_resample)

返回:

        Date  price                      
               last    min    max     sum
0 2018-01-09  88.22  88.22  88.28  176.50
1 2018-01-11  88.08  87.82  88.08  175.90
2 2018-01-16  88.35  88.35  89.60  177.95
3 2018-01-18  90.10  90.10  90.14  180.24
4 2018-01-22  91.61  90.00  91.61  181.61
5 2018-01-24  91.82  91.82  91.90  183.72
6 2018-01-26  94.06  92.33  94.06  186.39

【讨论】:

  • 有趣的 Anton - 在您的第一个解决方案中,我看到 .min() 从 1/8 开始,而 .last().max() 从 1/9 开始。在一个完美的世界里,它们都会在同一天开始和结束。
  • Max 也返回日期的最大值。看看我的替代方案。
  • 谢谢。第二个解决方案 - 我试图弄清楚如何关闭第二行并向后看,而不是向前看(在 1/8 上,我们正在确定今天和第二天的最小值,1/8-1/9) .
  • 我粘贴了 Excel 快照。非常感谢您在这方面与我合作。
  • @MJS 在这种情况下只需使用[1::2] 获取第二个元素,对吗?查看我的更新。
【解决方案2】:

将 np.repeat 与数组切片一起使用,您可以创建一个重新采样的数据框,其中日期(索引)重复两次。

df_resample = df.set_index(np.repeat(df.index[::2],2)[:len(df)])
# outputs:
            price
date
2018-01-08  88.28
2018-01-08  88.22
2018-01-10  87.82
2018-01-10  88.08
2018-01-12  89.60
2018-01-12  88.35
2018-01-17  90.14
2018-01-17  90.10
2018-01-19  90.00
2018-01-19  91.61
2018-01-23  91.90
2018-01-23  91.82
2018-01-25  92.33
2018-01-25  94.06

然后像往常一样分组产生所需的输出:

df_resampled.groupby(level=0).agg(['last', 'min', 'max', 'sum'])

            price
             last    min    max     sum
date
2018-01-08  88.22  88.22  88.28  176.50
2018-01-10  88.08  87.82  88.08  175.90
2018-01-12  88.35  88.35  89.60  177.95
2018-01-17  90.10  90.10  90.14  180.24
2018-01-19  91.61  90.00  91.61  181.61
2018-01-23  91.82  91.82  91.90  183.72
2018-01-25  94.06  92.33  94.06  186.39

【讨论】:

    【解决方案3】:

    我认为这也可能有效,有点颠倒步骤......

    df['price'].rolling(window=2).max().iloc[1::2]
    

    【讨论】:

      猜你喜欢
      • 2013-01-13
      • 1970-01-01
      • 2011-11-21
      • 1970-01-01
      • 2014-11-10
      • 1970-01-01
      • 2021-09-05
      • 2019-01-26
      相关资源
      最近更新 更多