python - pandas - 在特定日期边界上分割日期范围

标签 python pandas dataframe

我有一个日期范围的 DataFrame(实际的 DataFrame 附加了更多数据,但具有相同的 startend 列)。最终需要在周日至周六的基础上逐周分析数据。因此,我想遍历 DataFrame,并分割从周六到周日的任何日期范围(startfinish)。例如,给定 DataFrame:

import pandas as pd

date_ranges = [
    {'start': '2020-01-16 22:30:00', 'end': '2020-01-17 01:00:00'}, # spans thurs-fri, ok as is
    {'start': '2020-01-17 04:30:00', 'end': '2020-01-17 12:30:00'}, # no span, ok as is
    {'start': '2020-01-18 10:15:00', 'end': '2020-01-18 14:00:00'}, # no span, ok as is
    {'start': '2020-01-18 22:30:00', 'end': '2020-01-19 02:00:00'}  # spans sat-sun, must split
]
data_df = pd.DataFrame(date_ranges)

我希望我的结果看起来像:

result_ranges = [
    {'start': '2020-01-16 22:30:00', 'end': '2020-01-17 01:00:00'}, # spans thurs-fri, ok as is
    {'start': '2020-01-17 04:30:00', 'end': '2020-01-17 12:30:00'}, # no span, ok as is
    {'start': '2020-01-18 10:15:00', 'end': '2020-01-18 14:00:00'}, # no span, ok as is
    {'start': '2020-01-18 22:30:00', 'end': '2020-01-19 00:00:00'}, # split out saturday portion
    {'start': '2020-01-19 00:00:00', 'end': '2020-01-19 02:00:00'}  # and the sunday portion
]

result_df = pd.DataFrame(result_ranges)

任何关于如何在 pandas 中有效地做到这一点的想法将不胜感激。目前我正在做坏事,并迭代行,当数据集变大时,速度非常慢。

最佳答案

像这样的操作总是很困难,在某种程度上我认为循环是必要的。在这种情况下,我们可以遍历边缘,而不是遍历行。当您的数据跨度的周数远小于您拥有的行数时,这应该会带来相当大的性能提升。

我们定义边并在必要时修改 DataFrame 端点。最后,所需的 DataFrame 是我们修改的 DataFrame 的剩余部分,加上我们存储在 l 中的所有单独时间跨度。原始索引被保留,因此您可以准确地看到哪些行被分割。如果单个时间跨度跨越 N 条边,它将被分成 N+1 个单独的行。

设置

import pandas as pd

df[['start', 'end']]= df[['start', 'end']].apply(pd.to_datetime)

edges = pd.date_range(df.start.min().normalize() - pd.Timedelta(days=7),
                      df.end.max().normalize() + pd.Timedelta(days=7), freq='W-Sun')

代码

l = []
for edge in edges:
    m = df.start.lt(edge) & df.end.gt(edge)  # Rows to modify
    l.append(df.loc[m].assign(end=edge))     # Clip end of modified rows
    df.loc[m, 'start'] = edge                # Fix start for next edge

result = pd.concat(l+[df]).sort_values('start')

输出

                start                 end
0 2020-01-16 22:30:00 2020-01-17 01:00:00
1 2020-01-17 04:30:00 2020-01-17 12:30:00
2 2020-01-18 10:15:00 2020-01-18 14:00:00
3 2020-01-18 22:30:00 2020-01-19 00:00:00
3 2020-01-19 00:00:00 2020-01-19 02:00:00

关于python - pandas - 在特定日期边界上分割日期范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59791843/

相关文章:

python - 更改 python 中列表的特定元素?

python - 无法导入 Airflow 提供程序包

python pandas对象类型dict获取值时出错

python - 带有 AR 误差的线性回归模型 python

python - Pandas :计算一列每两行的平均值并将其放入新列

Python Pandas - 如何从序列创建数据框

python - 如何编写动态代码让多元回归模型自动计算r方值并输出数据

python - Pandas 'eval' 与 NaN

python - DataFrame.groupby.apply() 与 lambda 函数

Python ArgumentParser 嵌套参数