看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
Pandas 具有简单,强大和高效的功能,可在频率转换期间执行重采样操作(例如,将秒数据转换为5分钟数据)。 这在金融应用程序中非常普遍,但不仅限于此。
resample() 是一个基于时间的分组依据,后面是每个分组的聚合方法。
rng = pd.date_range('1/1/2012', periods=1000, freq='S')
ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)
# 每5分钟进行一次聚合
ts.resample('5Min').sum()
'''
2012-01-01 00:00:00 74477
2012-01-01 00:05:00 74834
2012-01-01 00:10:00 76489
2012-01-01 00:15:00 25095
Freq: 5T, dtype: int64
'''
重采样功能非常灵活,您可以指定许多不同的参数来控制频率转换和重采样操作。
通过分派可用的任何函数(类似于 grouby)都可以作为返回对象的方法,包括 sum,mean,std,sem,max,min,mid,median,first,last,ohlc:
ts.resample('5Min').mean() # 平均
ts.resample('5Min').max() # 最大值
美国线(英语:Open-High-Low-Close chart,OHLC chart),以竖立的线条表现股票价格的变化,可以呈现“开盘价、最高价、最低价、收盘价”,竖线呈现最高价和最低价间的价差间距,左侧横线代表开盘价,右侧横线代表收盘价,绘制上较K线简单。另有一种美国线仅呈现“最高价、最低价、收盘价”(HLC)三项讯息。
ts.resample('5Min').ohlc()
''' open high low close
2012-01-01 00:00:00 84 499 5 435
2012-01-01 00:05:00 229 497 1 440
2012-01-01 00:10:00 171 499 1 201
2012-01-01 00:15:00 431 499 0 289
'''
对于采样,可以将 closed 设置为“ left”或“ right”,以指定关闭区间的哪一端:
ts.resample('5Min', closed='right').mean()
ts.resample('5Min', closed='left').mean()
像 label 和 loffset 这样的参数用于操纵结果标签。 label 指定结果是用间隔的开始还是结束标记,loffset 对输出标签执行时间调整。
ts.resample('5Min').mean() # 默认 label='left'
ts.resample('5Min', label='left').mean()
ts.resample('5Min', label='left', loffset='1s').mean()
上采样又称图像插值,其主要目的是通过放大原图像,进而可以在更高分辨率的设备上显示。图像放大几乎都是采用内插值方法,即在原有图像像素的基础上在像素点之间采用合适的插值算法插入新的元素。
对于上采样,您可以指定一种上采样的方法,并指定 limit 参数以对创建的间隙进行插值:
# 从每秒到每250毫秒
ts[:2].resample('250L').asfreq()
'''
2012-01-01 00:00:00.000 84.0
2012-01-01 00:00:00.250 NaN
2012-01-01 00:00:00.500 NaN
2012-01-01 00:00:00.750 NaN
2012-01-01 00:00:01.000 61.0
Freq: 250L, dtype: float64
'''
ts[:2].resample('250L').ffill()
'''
2012-01-01 00:00:00.000 84
2012-01-01 00:00:00.250 84
2012-01-01 00:00:00.500 84
2012-01-01 00:00:00.750 84
2012-01-01 00:00:01.000 61
Freq: 250L, dtype: int64
'''
ts[:2].resample('250L').ffill(limit=2)
'''
2012-01-01 00:00:00.000 84.0
2012-01-01 00:00:00.250 84.0
2012-01-01 00:00:00.500 84.0
2012-01-01 00:00:00.750 NaN
2012-01-01 00:00:01.000 61.0
Freq: 250L, dtype: float64
'''
压缩感知(Compressed sensing),也被称为压缩采样(Compressive sampling)或稀疏采样(Sparse sampling),是一种寻找欠定线性系统的稀疏解的技术。压缩感知被应用于电子工程尤其是信号处理中,用于获取和重构稀疏或可压缩的信号。
相对于要重采样的时间量,稀疏时间序列的点要少得多。 天真地对稀疏序列进行升采样可能会产生很多中间值。 当您不想使用一种方法来填充这些值时,例如 fill_method 为 None,则中间值将用 NaN 填充。由于重采样是基于时间的分组依据,因此以下是仅对并非全部为NaN的组进行有效重采样的方法。
rng = pd.date_range('2014-1-1', periods=100, freq='D') + pd.Timedelta('1s')
ts = pd.Series(range(100), index=rng)
# 如果我们想对整个系列重新采样:
ts.resample('3T').sum()
'''
2014-01-01 00:00:00 0
2014-01-01 00:03:00 0
2014-01-01 00:06:00 0
2014-01-01 00:09:00 0
2014-01-01 00:12:00 0
..
2014-04-09 23:48:00 0
2014-04-09 23:51:00 0
2014-04-09 23:54:00 0
2014-04-09 23:57:00 0
2014-04-10 00:00:00 99
Freq: 3T, Length: 47521, dtype: int64
'''
取而代之的是,我们只能对那些我们拥有点的组重新采样,如下所示:
from functools import partial
from pandas.tseries.frequencies import to_offset
def round(t, freq):
freq = to_offset(freq)
return pd.Timestamp((t.value // freq.delta.value) * freq.delta.value)
ts.groupby(partial(round, freq='3T')).sum()
'''
2014-01-01 0
2014-01-02 1
2014-01-03 2
2014-01-04 3
2014-01-05 4
..
2014-04-06 95
2014-04-07 96
2014-04-08 97
2014-04-09 98
2014-04-10 99
Length: 100, dtype: int64
'''
类似于 aggregating API, groupby API, 和窗口方法 api, Resampler 也适用相关方法。重新采样DataFrame时,默认值是对具有相同功能的所有列进行操作:
df = pd.DataFrame(np.random.randn(1000, 3),
index=pd.date_range('1/1/2012', freq='S', periods=1000),
columns=['A', 'B', 'C'])
r = df.resample('3T')
r.mean()
'''
A B C
2012-01-01 00:00:00 -0.033823 -0.121514 -0.081447
2012-01-01 00:03:00 0.056909 0.146731 -0.024320
2012-01-01 00:06:00 -0.058837 0.047046 -0.052021
2012-01-01 00:09:00 0.063123 -0.026158 -0.066533
2012-01-01 00:12:00 0.186340 -0.003144 0.074752
2012-01-01 00:15:00 -0.085954 -0.016287 -0.050046
'''
我们可以选择一个或多个特定列:
r['A'].mean()
'''
2012-01-01 00:00:00 -0.033823
2012-01-01 00:03:00 0.056909
2012-01-01 00:06:00 -0.058837
2012-01-01 00:09:00 0.063123
2012-01-01 00:12:00 0.186340
2012-01-01 00:15:00 -0.085954
Freq: 3T, Name: A, dtype: float64
'''
r[['A', 'B']].mean()
'''
A B
2012-01-01 00:00:00 -0.033823 -0.121514
2012-01-01 00:03:00 0.056909 0.146731
2012-01-01 00:06:00 -0.058837 0.047046
2012-01-01 00:09:00 0.063123 -0.026158
2012-01-01 00:12:00 0.186340 -0.003144
2012-01-01 00:15:00 -0.085954 -0.016287
'''
多个聚合方式:
r['A'].agg([np.sum, np.mean, np.std])
r.agg([np.sum, np.mean]) # 每个列
# 不同的聚合方式
r.agg({'A': np.sum,
'B': lambda x: np.std(x, ddof=1)})
# 用字符指定
r.agg({'A': 'sum', 'B': 'std'})
r.agg({'A': ['sum', 'std'], 'B': ['mean', 'std']})
如果索引不是时间,可以指定采样的时间列:
# date 是一个普通列
df.resample('M', on='date').sum()
df.resample('M', level='d').sum() # 多层索引
迭代采样对象:
small = pd.Series(range(6),
index=pd.to_datetime(['2017-01-01T00:00:00',
'2017-01-01T00:30:00',
'2017-01-01T00:31:00',
'2017-01-01T01:00:00',
'2017-01-01T03:00:00',
'2017-01-01T03:05:00'])
)
resampled = small.resample('H')
for name, group in resampled:
print("Group: ", name)
print("-" * 27)
print(group, end="\n\n")
更新时间:2024-08-15 09:00:11 标签:pandas 时间 重采样