共计 5642 个字符,预计需要花费 15 分钟才能阅读完成。
重采样是工夫序列剖析中解决时序数据的一项根本技术。它是对于将工夫序列数据从一个频率转换到另一个频率,它能够更改数据的工夫距离,通过上采样减少粒度,或通过下采样缩小粒度。在本文中,咱们将深入研究 Pandas 中从新采样的关键问题。
为什么重采样很重要?
工夫序列数据达到时通常带有可能与所需的剖析距离不匹配的工夫戳。例如以不规则的距离收集数据,但须要以统一的频率进行建模或剖析。
重采样分类
重采样次要有两种类型:
1、Upsampling
上采样能够减少数据的频率或粒度。这意味着将数据转换成更小的工夫距离。
2、Downsampling
下采样包含缩小数据的频率或粒度。将数据转换为更大的工夫距离。
重采样的利用
重采样的利用非常宽泛:
在财务剖析中,股票价格或其余财务指标可能以不规则的距离记录。从新能够将这些数据与交易策略的工夫框架 (如每日或每周) 保持一致。
物联网 (IoT) 设施通常以不同的频率生成数据。从新采样能够标准化剖析数据,确保统一的工夫距离。
在创立工夫序列可视化时,通常须要以不同的频率显示数据。从新采样够调整绘图中的细节程度。
许多机器学习模型都须要具备统一工夫距离的数据。在为模型训练筹备工夫序列数据时,重采样是必不可少的。
重采样过程
重采样过程通常包含以下步骤:
首先抉择要从新采样的工夫序列数据。该数据能够采纳各种格局,包含数值、文本或分类数据。
确定您心愿从新采样数据的频率。这能够是减少粒度 (上采样) 或缩小粒度(下采样)。
抉择从新采样办法。罕用的办法包含均匀、求和或应用插值技术来填补数据中的空白。
在上采样时,可能会遇到原始工夫戳之间短少数据点的状况。插值办法,如线性或三次样条插值,能够用来预计这些值。
对于下采样,通常会在每个指标区间内聚合数据点。常见的聚合函数包含 sum、mean 或 median。
评估重采样的数据,以确保它合乎剖析指标。检查数据的一致性、完整性和准确性。
Pandas 中的 resample()办法
resample 能够同时操作 Pandas Series 和 DataFrame 对象。它用于执行聚合、转换或工夫序列数据的下采样和上采样等操作。
上面是
resample()
办法的根本用法和一些常见的参数:
import pandas as pd
# 创立一个示例工夫序列数据框
data = {'date': pd.date_range(start='2023-01-01', end='2023-12-31', freq='D'),
'value': range(365)}
df = pd.DataFrame(data)
# 将日期列设置为索引
df.set_index('date', inplace=True)
# 应用 resample()办法进行从新采样
# 将每日数据转换为每月数据并计算每月的总和
monthly_data = df['value'].resample('M').sum()
# 将每月数据转换为每季度数据并计算每季度的平均值
quarterly_data = monthly_data.resample('Q').mean()
# 将每季度数据转换为每年数据并计算每年的最大值
annual_data = quarterly_data.resample('Y').max()
print(monthly_data)
print(quarterly_data)
print(annual_data)
在上述示例中,咱们首先创立了一个示例的工夫序列数据框,并应用
resample()
办法将其转换为不同的工夫频率(每月、每季度、每年)并利用不同的聚合函数(总和、平均值、最大值)。
resample()
办法的参数:
- 第一个参数是工夫频率字符串,用于指定从新采样的指标频率。常见的选项包含
'D'
(每日)、'M'
(每月)、'Q'
(每季度)、'Y'
(每年)等。 - 你能够通过第二个参数
how
来指定聚合函数,例如'sum'
、'mean'
、'max'
等,默认是'mean'
。 - 你还能够应用
closed
参数来指定每个区间的闭合端点,可选的值包含'right'
、'left'
、'both'
、'neither'
,默认是'right'
。 - 应用
label
参数来指定从新采样后的标签应用哪个工夫戳,可选的值包含'right'
、'left'
、'both'
、'neither'
,默认是'right'
。 - 能够应用
loffset
参数来调整从新采样后的工夫标签的偏移量。 - 最初,你能够应用聚合函数的特定参数,例如
'sum'
函数的min_count
参数来指定非 NA 值的最小数量。
1、指定列名
默认状况下,Pandas 的 resample()办法应用 Dataframe 或 Series 的索引,这些索引应该是工夫类型。然而,如果心愿基于特定列从新采样,则能够应用 on 参数。这容许您抉择一个特定的列进行从新采样,即便它不是索引。
df.reset_index(drop=False, inplace=True)
df.resample('W', on='index')['C_0'].sum().head()
在这段代码中,应用 resample()办法对 ’index’ 列执行每周重采样,计算每周 ’C_0’ 列的和。
2、指定开始和完结的工夫距离
closed 参数容许重采样期间管制关上和敞开距离。默认状况下,一些频率,如 ’M’,‘A’,‘Q’,‘BM’,‘BA’,‘BQ’ 和 ’W’ 是右闭的,这意味着包含右边界,而其余频率是左闭的,其中包含左边界。在转换数据频率时,能够依据须要手动设置敞开距离。
df = generate_sample_data_datetime()
pd.concat([df.resample('W', closed='left')['C_0'].sum().to_frame(name='left_closed'),
df.resample('W', closed='right')['C_0'].sum().to_frame(name='right_closed')],
axis=1).head(5)
在这段代码中,咱们演示了将日频率转换为周频率时左闭距离和右闭距离的区别。
3、输入后果管制
label 参数能够在重采样期间管制输入后果的标签。默认状况下,一些频率应用组内的右边界作为输入标签,而其余频率应用左边界。在转换数据频率时,能够指定是要应用左边界还是右边界作为输入标签。
df = generate_sample_data_datetime()
df.resample('W', label='left')['C_0'].sum().to_frame(name='left_boundary').head(5)
df.resample('W', label='right')['C_0'].sum().to_frame(name='right_boundary').head(5)
在这段代码中,输入标签是依据在 label 参数中指定“left”还是“right”而变动的,倡议在理论利用时显式指定,这样能够缩小混同。
4、汇总统计数据
重采样能够执行聚合统计,相似于应用 groupby。应用 sum、mean、min、max 等聚合办法来汇总从新采样距离内的数据。这些聚合办法相似于 groupby 操作可用的聚合办法。
df.resample('D').sum()
df.resample('W').mean()
df.resample('M').min()
df.resample('Q').max()
df.resample('Y').count()
df.resample('W').std()
df.resample('M').var()
df.resample('D').median()
df.resample('M').quantile([0.25, 0.5, 0.75])
custom_agg = lambda x: x.max() - x.min()
df.resample('W').apply(custom_agg)
上采样和填充
在工夫序列数据分析中,上采样和下采样是用来操纵数据观测频率的技术。这些技术对于调整工夫序列数据的粒度以匹配剖析需要十分有价值。
咱们学生成一些数据
import pandas as pd
import numpy as np
def generate_sample_data_datetime():
np.random.seed(123)
number_of_rows = 365 * 2
num_cols = 5
start_date = '2023-09-15' # You can change the start date if needed
cols = ["C_0", "C_1", "C_2", "C_3", "C_4"]
df = pd.DataFrame(np.random.randint(1, 100, size=(number_of_rows, num_cols)), columns=cols)
df.index = pd.date_range(start=start_date, periods=number_of_rows)
return df
df = generate_sample_data_datetime()
上采样包含减少数据的粒度,这意味着将数据从较低的频率转换为较高的频率。
假如您有下面生成的每日数据,并心愿将其转换为 12 小时的频率,并在每个距离内计算“C_0”的总和:
df.resample('12H')['C_0'].sum().head(10)
代码将数据重采样为 12 小时的距离,并在每个距离内对 ’ C_0 ‘ 利用总和聚合。这个.head(10)用于显示后果的前 10 行。
在上采样过程中,特地是从较低频率转换到较高频率时,因为新频率引入了间隙,会遇到失落数据点的状况。所以须要对间隙的数据进行填充,填充个别应用以下几个办法:
向前填充 - 前一个可用的值填充缺失的值。能够应用 limit 参数限度正向填充的数量。
df.resample('8H')['C_0'].ffill(limit=1)
反向填充 - 用下一个可用的值填充缺失的值。
df.resample('8H')['C_0'].bfill(limit=1)
最近填充 - 用最近的可用值填充缺失的数据,该值能够是向前的,也能够是向后的。
df.resample('8H')['C_0'].nearest(limit=1)
Fillna —联合了后面三个办法的性能。能够指定办法(例如,’pad’/’ fill’,‘bfill’,‘nearest’),并应用 limit 参数进行数量管制。
df.resample('8H')['C_0'].fillna(method='pad', limit=1)
Asfreq- 指定一个固定的值来填充所有缺失的局部一次。例如,能够应用 -999 填充缺失的值。
df.resample('8H')['C_0'].asfreq(-999)
插值办法 - 能够利用各种插值算法。
df.resample('8H').interpolate(method='linear').applymap(lambda x: round(x, 2))
一些罕用的函数
1、应用 agg 进行聚合
result = df.resample('W').agg(
{'C_0': ['sum', 'mean'],
'C_1': lambda x: np.std(x, ddof=1)
}
).head()
应用 agg 办法将每日工夫序列数据从新采样到每周频率。并为不同的列指定不同的聚合函数。对于“C_0”,计算总和和平均值,而对于“C_1”,计算标准差。
2、应用 apply 聚合
def custom_agg(x):
agg_result = {'C_0_mean': round(x['C_0'].mean(), 2),
'C_1_sum': x['C_1'].sum(),
'C_2_max': x['C_2'].max(),
'C_3_mean_plus1': round(x['C_3'].mean() + 1, 2)
}
return pd.Series(agg_result)
result = df.resample('W').apply(custom_agg).head()
定义了一个名为 custom_agg 的自定义聚合函数,它将 DataFrame x 作为输出,并在不同列上计算各种聚合。应用 apply 办法将数据从新采样到每周的频率,并利用自定义聚合函数。
3、应用 transform 进行变换
df['C_0_cumsum'] = df.resample('W')['C_0'].transform('cumsum')
df['C_0_rank'] = df.resample('W')['C_0'].transform('rank')
result = df.head(10)
应用 transform 办法来计算每周组中 ’C_0’ 变量的累积和排名。DF 的原始索引构造放弃不变。
4、应用 pipe 进行管道操作
result = df.resample('W')['C_0', 'C_1'] \
.pipe(lambda x: x.cumsum()) \
.pipe(lambda x: x['C_1'] - x['C_0'])
result = result.head(10)
应用管道办法对下采样的 ’C_0’ 和 ’C_1’ 变量进行链式操作。cumsum 函数计算累积和,第二个管道操作计算每个组的 ’C_1’ 和 ’C_0’ 之间的差值。像管道一样执行程序操作。
总结
工夫序列的重采样是将工夫序列数据从一个工夫频率(例如每日)转换为另一个工夫频率(例如每月或每年),并且通常随同着对数据进行聚合操作。重采样是工夫序列数据处理中的一个要害操作,通过进行重采样能够更好地了解数据的趋势和模式。
在 Python 中,能够应用 Pandas 库的
resample()
办法来执行工夫序列的重采样。
https://avoid.overfit.cn/post/cf6fba5f6cbe49619738f2181b1bbd70
作者:JIN