盘点一个工作中Python自动化处理实战问题(中篇)

2024-01-03 13:51:33 浏览数 (1)

生亦何欢,死亦何苦。

大家好,我是皮皮。

一、前言

前几天在Python最强王者交流群【哎呦喂 是豆子~】问了一个工作中Python自动化处理实战问题,一起来看看吧。问题描述:

数据在提供的数据表中,在表有编号、环节、审核人、金额、结束时间5列,对【编号、环节、审核人、金额】四条件进行分组,分组内结束时间升序排列,分组内结束时间相差20秒以内的,只保留第一条记录。

大佬再请问下 分组内结束时间相差20秒以内的,只保留第一条记录 这个怎么实现? 这个做出来的老是有问题 有个窗口函数 用了数据又对不太上。

上一篇文章【瑜亮老师】给出了自己的解答,这一篇文章我们一起来看看【小小明】大佬的解答。

二、实现过程

这里【小小明】给了一份代码,如下所示:

代码语言:javascript复制
import pandas as pd

def func(df_split):
    last_time = None
    idx = []
    for row in df_split.itertuples():
        if last_time is None or (row.结束时间-last_time).total_seconds() > 20:
            idx.append(row.Index)
            last_time = row.结束时间
    return df_split.loc[idx]

df = pd.read_excel("工作量计算.xlsx")
df.sort_values(["编号", "环节", "审核人", "金额", "结束时间"]).groupby(
    ["编号", "环节", "审核人", "金额"], as_index=False).apply(func)

代码运行后,结果和【瑜亮老师】的答案一致,也是还剩余3394行:

后来【小小明】大佬继续给优化了一下,代码如下:

代码语言:javascript复制
import pandas as pd


def func(df_split):
    last_time = None
    idx = []
    for row in df_split.itertuples():
        if last_time is None or (row.结束时间-last_time).total_seconds() > 20:
            idx.append(row.Index)
            last_time = row.结束时间
    return df_split.loc[idx]


df = pd.read_excel("工作量计算.xlsx")
result = (
    df.sort_values(["编号", "环节", "审核人", "金额", "结束时间"])
    .groupby(["编号", "环节", "审核人", "金额"], as_index=False)
    .apply(func).droplevel(0)
)
result

去除多余的索引加个.droplevel(0)。

针对上一篇文章中【瑜亮老师】的答案,【小小明】大佬继续找他的代码基础上进行了优化,优化后的代码如下所示:

代码语言:javascript复制
简化后如下:

import pandas as pd


def filter_rows(group):
    diff = group.结束时间.diff()
    mask = diff.dt.total_seconds() < 20
    return group[~mask].drop_duplicates(keep='first')


df = pd.read_excel('工作量计算.xlsx')
df = df.sort_values(["编号", "环节", "审核人", "金额", "结束时间"])
result = df.groupby(['编号', '环节', '审核人', '金额'], as_index=False).apply(
    filter_rows).droplevel(0)
result

顺利地解决了粉丝的问题。

三、总结

大家好,我是皮皮。这篇文章主要盘点了一个工作中Python自动化处理实战问题,文中针对该问题,给出了具体的解析和代码实现,帮助粉丝顺利解决了问题。

最后感谢粉丝【哎呦喂 是豆子~】提出的问题,感谢【小小明】、【瑜亮老师】、【隔壁

0 人点赞