pandas 比较同一Dataframe列中的日期

yhuiod9q  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(153)

我在比较同一 Dataframe /列中的日期时遇到问题。
我在同一个 Dataframe 中有订单数据和呼叫数据。
我正在尝试比较订单的开始时间和呼叫的开始时间。
如果呼叫START时间在Order Creation的30天内,我想将Tag_x和Tag_z列中的值添加到呼叫行(附件中的最后两行)。
如果我们有多个"Order created"值,我想将Tag_x和Tag_z添加到调用行(格式如下:标签1、标签2 ...)
附件是数据样本。
| 病例ID|活动名称|启动|最小源系统|标签_x|标签_z|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 一百一十一|创建订单|2021年3月16日星期二|不合格|家庭电话安装|声音|
| 一百一十一|现场工作订单打开|2021年3月16日星期二|FWDS|家庭电话安装|声音|
| 一百一十一|工单-完成|2021年3月16日星期二|FWDS|家庭电话安装|声音|
| 一百一十一|现场工作订单完成|2021年3月18日星期四|FWDS|家庭电话安装|声音|
| 一百一十一|创建订单|2022年5月4日星期三|不合格|家庭安防安装|安全|
| 一百一十一|现场工作订单打开|2022年5月4日星期三|FWDS|家庭安防安装|安全|
| 一百一十一|工单-完成|2022年5月4日星期三|FWDS|家庭安防安装|安全|
| 一百一十一|现场工作订单完成|2022年5月5日星期四|FWDS|家庭安防安装|安全|
| 一百一十一|票据签发|2022年5月10日星期二||||
| 一百一十一|呼叫开始|2022年5月17日星期二|一般|||
| 一百一十一|纯纤维-TS|2022年5月17日星期二|一般|||
预期输出:
| 病例ID|活动名称|启动|最小源系统|标签_x|标签_z|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 一百一十一|创建订单|2021年3月16日星期二|不合格|家庭电话安装|声音|
| 一百一十一|现场工作订单打开|2021年3月16日星期二|FWDS|家庭电话安装|声音|
| 一百一十一|工单-完成|2021年3月16日星期二|FWDS|家庭电话安装|声音|
| 一百一十一|现场工作订单完成|2021年3月18日星期四|FWDS|家庭电话安装|声音|
| 一百一十一|创建订单|2022年5月4日星期三|不合格|家庭安防安装|安全|
| 一百一十一|现场工作订单打开|2022年5月4日星期三|FWDS|家庭安防安装|安全|
| 一百一十一|工单-完成|2022年5月4日星期三|FWDS|家庭安防安装|安全|
| 一百一十一|现场工作订单完成|2022年5月5日星期四|FWDS|家庭安防安装|安全|
| 一百一十一|票据签发|2022年5月10日星期二||||
| 一百一十一|呼叫开始|2022年5月17日星期二|一般|家庭电话安装,家庭安防安装|语音,安全|
| 一百一十一|纯纤维-TS|2022年5月17日星期二|一般|家庭电话安装,家庭安防安装|语音,安全|
我试过将数据拆分成两个独立的 Dataframe (订单和调用),然后迭代行,但是,我不确定是否正确使用了iterrows()。

dfcall= df[df['Activity Name']=="Call Start"]
dfcall['Tag_x']=nan
dfcall['Tag_z']=nan
dfcall=dfcall[['CASE ID','Activity Name','START','Tag_x','Tag_z']].reset_index(drop=True)
dforder=df[df['Activity Name']=="Order created"].reset_index(drop=True)
dforder=dforder[['CASE ID','Activity Name','START','Tag_x','Tag_z']].reset_index(drop=True)

for index, row_c in dfcall.iterrows():
for index, row_o in dforder.iterrows():
    if (row_c['CASE ID']==row_o['CASE ID']) & (row_c['START']>row_o['START'])& (((row_c['START'] - row_o['START']).total_seconds()/60/60)<=720): 
        y=row_o['Tag_x']
        row_c['Tag_x']=y+" "+"|"+" "+row_o['Tag_x']
wnvonmuf

wnvonmuf1#

这就是你要找的吗?

import pandas as pd

df = pd.DataFrame(
    [
        [
            111,
            "Order created",
            "Friday, May 6, 2022",
            "NC",
            "Home Phone Installation",
            "VOICE",
        ],
        [
            111,
            "Fielded Work Order Open",
            "Tuesday, March 16, 2021",
            "FWDS",
            "Home Phone Installation",
            "VOICE",
        ],
        [
            111,
            "Job - COMPLETE",
            "Tuesday, March 16, 2021",
            "FWDS",
            "Home Phone Installation",
            "VOICE",
        ],
        [
            111,
            "Fielded Work Order Completed",
            "Thursday, March 18, 2021",
            "FWDS",
            "Home Phone Installation",
            "VOICE",
        ],
        [
            111,
            "Order created",
            "Wednesday, May 4, 2022",
            "NC",
            "Home Security Installation",
            "SECURITY",
        ],
        [
            111,
            "Fielded Work Order Open",
            "Wednesday, May 4, 2022",
            "FWDS",
            "Home Security Installation",
            "SECURITY",
        ],
        [
            111,
            "Job - COMPLETE",
            "Wednesday, May 4, 2022",
            "FWDS",
            "Home Security Installation",
            "SECURITY",
        ],
        [
            111,
            "Fielded Work Order Completed",
            "Thursday, May 5, 2022",
            "FWDS",
            "Home Security Installation",
            "SECURITY",
        ],
        [111, "Bill Issued", "Tuesday, May 10, 2022", "", "", ""],
        [111, "Call Start", "Tuesday, May 17, 2022", "Gen", "", ""],
        [111, "PureFibre-TS", "Tuesday, May 17, 2022", "Gen", "", ""],
    ],
    columns=[
        "CASE ID",
        "Activity Name",
        "START",
        "minit_source_system",
        "Tag_x",
        "Tag_z",
    ],
)

df['START'] = pd.to_datetime(df['START'])

def tag_join(grp):
    """Join the tags together.

    Parameters
    ----------
    grp : pd.DataFrame
        A dataframe representing one group from the data to join tag columns
        values together. Should have columns "Tag_x" and "Tag_z".

    Returns
    -------
    pd.DataFrame
        Dataframe with a single row and values from columns "Tag_x" and
        "Tag_z" joined together.
    """
    tag_x = ", ".join(grp["Tag_x"].drop_duplicates())
    tag_z = ", ".join(grp["Tag_z"].drop_duplicates())
    grp.iloc[0][["Tag_x", "Tag_z"]] = [tag_x, tag_z]
    return grp.iloc[0]

def process_orders(grp: pd.DataFrame) -> pd.DataFrame:
    """Process the orders.

    Parameters
    ----------
    grp : pd.DataFrame
        A dataframe representing one group from the data to process.

    Returns
    -------
    pd.DataFrame
        Dataframe with the processed data.
    """
    call_start = grp[grp["Activity Name"] == "Call Start"]
    order_created = grp[grp["Activity Name"] == "Order created"]
    res = (
        call_start.drop(columns=["Tag_x", "Tag_z"])
        .merge(
            order_created.drop(columns=["Activity Name", "minit_source_system"]),
            how="outer",
            on="CASE ID",
            suffixes=("", "_y"),
        )
        .loc[lambda xdf: (xdf["START"] - xdf["START_y"]).dt.total_seconds() <= 2592000, :]
        .drop(columns=["START_y"])
    )
    return (
        pd.concat(
            [
                grp,
                res.groupby(
                    res.columns.difference(["Tag_x", "Tag_z"]).to_list(),
                    as_index=False
                )[["Tag_x", "Tag_z"]].apply(tag_join),
            ]
        )
        .drop_duplicates(
            subset=["CASE ID", "Activity Name", "START", "minit_source_system"],
            keep="last",
        )
        .reset_index(drop=True)
    )

final_df = df.groupby("CASE ID", as_index=False).apply(process_orders)

上面的代码创建了final_df Dataframe ,如下所示:
| | 病例ID|活动名称|启动|最小源系统|标签_x|标签_z|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 无|一百一十一|创建订单|2022年5月6日00时00分|不合格|家庭电话安装|声音|
| 1个|一百一十一|现场工作订单打开|2021年3月16日00时00分|FWDS|家庭电话安装|声音|
| 第二章|一百一十一|工单-完成|2021年3月16日00时00分|FWDS|家庭电话安装|声音|
| 三个|一百一十一|现场工作订单完成|2021年3月18日00时00分|FWDS|家庭电话安装|声音|
| 四个|一百一十一|创建订单|2022年5月4日00时00分|不合格|家庭安防安装|安全|
| 五个|一百一十一|现场工作订单打开|2022年5月4日00时00分|FWDS|家庭安防安装|安全|
| 六个|一百一十一|工单-完成|2022年5月4日00时00分|FWDS|家庭安防安装|安全|
| 七|一百一十一|现场工作订单完成|2022年5月5日00时00分|FWDS|家庭安防安装|安全|
| 八个|一百一十一|票据签发|2022年5月10日00时00分||||
| 九|一百一十一|纯纤维-TS|2022年5月17日00时00分|一般|||
| 十个|一百一十一|呼叫开始|2022年5月17日00时00分|一般|家庭电话安装,家庭安防安装|语音,安全|
将函数process_orderspandas.DataFrame.groupby配合使用,可以分别在每个'CASE ID'中应用日期比较。

观察

我已经将第一行中的'START'日期更改为"Friday, May 6, 2022"。我这样做是因为提供的原始示例数据只有一个符合规则的订单创建日期:"呼叫开始时间在订单创建后30天内"。

相关问题