
在处理时间序列数据时,我们经常会遇到数据不连续的情况,即某些日期的数据缺失。例如,在一个包含不同类别(如产品ID、用户ID等)的交易数据集中,每个类别的数据可能在时间轴上存在断点。为了进行更准确的分析或模型训练,我们通常需要补齐这些缺失的日期行,并为新生成的行填充默认值(如0)。
我们的目标是将以下原始DataFrame:
date key value
0 2023-12-01 K0 9
1 2023-12-03 K1 3
2 2023-12-04 K0 10
3 2023-12-01 K1 8转换为一个日期连续且数据完整的DataFrame,其中缺失日期对应的value填充为0,key值保持一致:
date key value
0 2023-12-01 K0 9
1 2023-12-02 K0 0
2 2023-12-03 K0 0
3 2023-12-04 K0 10
4 2023-12-01 K1 8
5 2023-12-02 K1 0
6 2023-12-03 K1 3
7 2023-12-04 K1 0解决此问题的核心在于:
我们将通过一个自定义函数结合groupby().apply()方法来实现这一目标。
首先,创建示例DataFrame并确保日期列为datetime类型:
import pandas as pd
# 原始数据
data = {
'date': ['2023-12-01', '2023-12-03', '2023-12-04', '2023-12-01'],
'key': ['K0', 'K1', 'K0', 'K1'],
'value': [9, 3, 10, 8]
}
df = pd.DataFrame(data)
# 将日期列转换为datetime类型,这是时间序列处理的基础
df['date'] = pd.to_datetime(df['date'])
print("原始DataFrame:")
print(df)我们定义一个辅助函数fill_missing_dates,它将对每个分组的数据进行处理。
def fill_missing_dates(group, global_min_date, global_max_date):
"""
对单个分组(group)的数据填充缺失日期,并补齐key和value。
参数:
group (pd.DataFrame): 当前分组的数据。
global_min_date (pd.Timestamp): 整个DataFrame的最小日期。
global_max_date (pd.Timestamp): 整个DataFrame的最大日期。
返回:
pd.DataFrame: 填充日期和值后的分组数据。
"""
# 生成从全局最小日期到全局最大日期的完整日期范围
full_date_range = pd.date_range(global_min_date, global_max_date)
# 将当前分组的'date'列设为索引,然后使用完整日期范围进行reindex
# reindex会引入缺失的日期行,这些行的其他列会是NaN
# reset_index()会将新的日期索引转换回列,并生成一个名为'index'的列
reindexed_group = group.set_index("date").reindex(full_date_range).reset_index()
# 将由reset_index()生成的'index'列重命名回'date'
reindexed_group = reindexed_group.rename(columns={'index': 'date'})
# 填充'key'列:
# 先使用ffill()(前向填充)填充NaN,再使用bfill()(后向填充)填充可能剩余的NaN。
# 这确保了在reindex后,新增的日期行能够继承其所属分组的key。
reindexed_group["key"] = reindexed_group["key"].ffill().bfill()
# 填充'value'列:
# 将NaN值填充为0,然后转换为整数类型。
reindexed_group["value"] = reindexed_group["value"].fillna(0).astype(int)
return reindexed_group现在,获取整个DataFrame的最小和最大日期,并将fill_missing_dates函数应用到按key分组的数据上。
# 获取整个DataFrame的最小和最大日期
global_min_date = df["date"].min()
global_max_date = df["date"].max()
# 按'key'分组,并对每个分组应用自定义函数
# group_keys=False避免在结果中创建额外的分组键层级
output_df = df.groupby("key", group_keys=False).apply(
fill_missing_dates,
global_min_date=global_min_date,
global_max_date=global_max_date
)
print("\n填充缺失日期后的DataFrame:")
print(output_df)输出结果:
原始DataFrame:
date key value
0 2023-12-01 K0 9
1 2023-12-03 K1 3
2 2023-12-04 K0 10
3 2023-12-01 K1 8
填充缺失日期后的DataFrame:
date key value
0 2023-12-01 K0 9
1 2023-12-02 K0 0
2 2023-12-03 K0 0
3 2023-12-04 K0 10
0 2023-12-01 K1 8
1 2023-12-02 K1 0
2 2023-12-03 K1 3
3 2023-12-04 K1 0通过groupby().apply()结合自定义函数,我们能够优雅且高效地解决Pandas DataFrame中分组时间序列数据的日期缺失问题。这种方法不仅保证了时间序列的完整性,也为后续的数据分析和建模奠定了坚实的基础。理解reindex、ffill、bfill以及fillna等Pandas核心函数的用法是掌握此类数据预处理的关键。
以上就是使用Pandas高效填充分组数据中的缺失日期序列的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号