繁体   English   中英

Python - Pandas,如何有效地按日期间隔内的月份进行聚合

[英]Python - Pandas, How to aggregate by months inside a date interval efficiently

我正在尝试使用开始日期和结束日期为一个月的数据集的 pandas 计算聚合指标,我需要高效地执行此操作,因为我的数据集可能有数百万行。 我的数据集是这样的

import pandas as pd
from dateutil.relativedelta import relativedelta

df = pd.DataFrame([["2020-01-01", "2020-05-01", 200],
                   ["2020-02-01", "2020-03-01", 100],
                   ["2020-03-01", "2020-04-01", 350],
                   ["2020-02-01", "2020-05-01", 500]], columns=["start", "end", "value"])

df["start"] = pd.to_datetime(df["start"])
df["end"] = pd.to_datetime(df["end"])

在此处输入图像描述

我想要这样的东西:

在此处输入图像描述

我尝试了两种方法,用开始日期和结束日期制作一个月的时间范围并将它们分解,然后按月分组:

df["months"] = df.apply(lambda x: pd.date_range(x["start"], x["end"], freq="MS"), axis=1)
df_explode = df.explode("months")
df_explode.groupby("months")["value"].agg(["mean", "sum", "std"])

另一个是逐月迭代,检查本月包含哪些月份行,然后聚合它们:

rows = []
for m in pd.date_range(df.start.min(), df.end.max(), freq="MS"):
    rows.append(df[(df.start <= m) & (m <= df.end)]["value"].agg(["mean", "sum", "std"]))
pd.DataFrame(rows, index=pd.date_range(df.start.min(), df.end.max(), freq="MS"))

第一种方法适用于较小的数据集,第二种方法适用于较大的数据集,但我想知道是否有更好的方法可以更好更快地完成这项工作。

非常感谢你

这类似于您的第二种方法,但已矢量化。 它假定您的开始日期和结束日期是月初。

month_starts = pd.date_range(df.start.min(), df.end.max(), freq="MS")[:-1].to_numpy()
contained = np.logical_and(
    np.greater_equal.outer(month_starts, df["start"].to_numpy()),
    np.less.outer(month_starts, df["end"].to_numpy()),
)
masked = np.where(contained, np.broadcast_to(df[["value"]].transpose(),contained.shape), np.nan)
pd.DataFrame(masked, index=month_starts).agg(["mean", "sum", "std"], axis=1)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM