看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
时序数据展开是将一个时间区间数据拆分为多个时间的操作,将原本的一行数据展开成多行,每行对应一个时间步。它可以用于许多应用场景,如如趋势分析、周期性分析、季节性分析等,还应用在绘制时序图、热力图、气泡图等。许多机器学习模型需要输入多个时间步的数据,如循环神经网络(RNN)、长短时记忆网络(LSTM)、卷积神经网络(CNN)等。展开时序数据可以将原始数据转换为这些模型可以接受的形式。
数据清洗和处理中,展开时序数据可以方便地进行数据清洗和处理,如填充缺失值、平滑数据、降采样、重采样等。信号处理时展开时序数据可以方便地进行信号处理,如滤波、傅里叶变换、小波变换等。因此,时序数据展开是时序数据处理中非常重要的一步,广泛应用于许多领域,如金融、医疗、气象、物联网等。
本例,我们用 Python 来完成一个类似的例子。
我们的数据用以下方式构造:
import pandas as pd
from io import StringIO
data = '''
合同编号 起始日期 结束日期
BH001 2023-02-20 2024-02-19
BH002 2023-04-01 2026-03-31
BH003 2022-04-10 2023-04-09
BH004 2023-03-01 2024-09-30
BH005 2023-02-01 2026-01-31
'''
df = pd.read_csv(StringIO(data), sep=r'\s+')
我们希望将以上数据按起始日期到结束日期展开,增加年和月列。例如上面的第一条数据,拆分成下面这种效果:
'''
合同编号 年 月
BH001 2023 2
BH001 2023 3
BH001 2023 4
BH001 2023 5
BH001 2023 6
BH001 2023 7
BH001 2023 8
BH001 2023 9
BH001 2023 10
BH001 2023 11
BH001 2023 12
BH001 2024 1
BH001 2024 2
'''
我们的思路如下:
根据思路,我们的代码如下:
(
df.assign(日期=df.apply(lambda s: pd.date_range(s.起始日期, s.结束日期), axis=1))
.explode('日期')
.assign(年=lambda d: d.日期.dt.year, 月=lambda d: d.日期.dt.month)
.filter(['合同编号', '年', '月'])
.drop_duplicates()
)
'''
合同编号 年 月
0 BH001 2023 2
0 BH001 2023 3
0 BH001 2023 4
0 BH001 2023 5
0 BH001 2023 6
.. ... ... ..
4 BH005 2025 9
4 BH005 2025 10
4 BH005 2025 11
4 BH005 2025 12
4 BH005 2026 1
[117 rows x 3 columns]
'''
代码使用了pandas库来进行数据处理和转换,下面是对每行代码的详细解释:
df.assign(日期=df.apply(lambda s: pd.date_range(s.起始日期, s.结束日期), axis=1))
:
这行代码是将数据框df中的每一行,按照其起始日期和结束日期生成一个日期范围,并将这个日期范围作为新列“日期”的值添加到数据框中。具体来说,apply方法对每一行进行操作,lambda函数以该行为输入,返回一个起始日期和结束日期间的日期范围,pd.date_range方法用于生成这个日期范围。最后assign方法将新生成的“日期”列添加到数据框中。
.explode('日期')
:
这行代码是将数据框中的每一行,按照“日期”列进行展开,即将每个日期范围转换成多行,每行只包含一个日期。explode方法用于展开数据框中的列,其参数为要展开的列名。
.assign(年=lambda d: d.日期.dt.year, 月=lambda d: d.日期.dt.month)
:
这行代码是为数据框添加两列,分别是年份和月份。这两列的值是从“日期”列中提取出来的,分别使用dt.year和dt.month方法提取每个日期的年份和月份,并使用assign方法将新生成的“年”和“月”列添加到数据框中。
filter(['合同编号', '年', '月'])
:
这行代码是对数据框进行列筛选,只保留“合同编号”、“年”和“月”三列。filter方法用于按照列名进行筛选,其参数为一个包含要保留的列名的列表。
drop_duplicates()
:
这行代码是对数据框进行去重操作,即去除重复的行。drop_duplicates方法用于去除重复的行,其默认参数为所有列都相同才算是重复行。在这个例子中,由于我们已经保留了“合同编号”、“年”和“月”三列,因此drop_duplicates方法只会根据这三列进行去重。
另外,还可以用 pd.period_range() 构造时间周期序列,使用后的完整代码如下:
(
df.assign(日期=df.apply(lambda s: pd.period_range(s.起始日期, s.结束日期, freq='M'), axis=1))
.explode('日期')
.assign(年=lambda d: d.日期.dt.year, 月=lambda d: d.日期.dt.month)
.filter(['合同编号', '年', '月'])
)
这样就完成了需求。
(完)
更新时间:2024-08-18 16:12:10 标签:pandas python 时序数据