Python pandas - 每第二行而不是每第二个工作日重新采样一次
Python pandas - resample every 2nd row rather than every 2nd business day
我正在处理股票价格数据,并希望每第二行而不是每第二个工作日 (resample('2B')
) 得到 resample()
到 return。障碍是在工作日登陆的任何假期。见下文,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()
。
谢谢。
预期输出:
为了获得稳定的解决方案,我会考虑以某种方式重新定义 B-days。
但是如果你重置索引你可以使用索引号和groupby:
df = df.reset_index()
df_resample = df.groupby(df.index // 2).min()
print(df_resample)
Returns:
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)
Returns:
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
使用 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
我认为这也可行,有点颠倒步骤...
df['price'].rolling(window=2).max().iloc[1::2]
我正在处理股票价格数据,并希望每第二行而不是每第二个工作日 (resample('2B')
) 得到 resample()
到 return。障碍是在工作日登陆的任何假期。见下文,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()
。
谢谢。
预期输出:
为了获得稳定的解决方案,我会考虑以某种方式重新定义 B-days。
但是如果你重置索引你可以使用索引号和groupby:
df = df.reset_index()
df_resample = df.groupby(df.index // 2).min()
print(df_resample)
Returns:
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)
Returns:
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
使用 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
我认为这也可行,有点颠倒步骤...
df['price'].rolling(window=2).max().iloc[1::2]