【问题标题】:Pandas time series difference in time units with apply and groupby熊猫时间序列的时间单位差异与apply和groupby
【发布时间】:2017-11-17 04:29:45
【问题描述】:

我有一个产品,其中包含产品通过的步骤。
即数据结构为: 产品 ID、订单 ID、新值、旧值、编辑日期。

我想要产品通过我们系统过渡的时间差和累计时间总和(以天为单位)。即总循环时间和步间循环时间。

我编写了以下代码,它运行良好,但仍然很慢。我希望有人可以提供更快的解决方案,因为目前处理具有 4 亿个处理步骤的 YTD 数据集需要数小时。

def f(df):
    df['diff'] = (df['Edit Date'].diff())/ np.timedelta64(1, 'D')
    df['sum'] = df['diff'].cumsum()
    print  len(df)
    return df

if __name__ == '__main__':
    df = pd.read_csv('May 2017.csv')
    df['Edit Date'] = pd.to_datetime(df['Edit Date'], format='%m/%d/%Y')
    df.sort_values(by=['Order ID','Edit Date',]  ,kind = 'mergesort', ascending=[1,1], inplace=True)
    df= df.groupby(['Order ID'])
    timediffference = df.apply(f)

这给了我我想要的东西,但它在大型数据集上速度很慢,在一个缓慢的月份通常会超过 2000 万行。想知道是否有一种方法可以更快地针对每个订单步骤组的整个日期列执行此操作,而不是尝试使用 apply。我尝试使用多核,但发现死路一条。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    Groupby 在使用 apply 时非常慢。您应该使用通过 groupby 对象实现的函数,即:

    df['diff'] = df.groupby('Order ID')['Edit Date'].diff() / np.timedelta64(1, 'D')
    df['sum'] = df.groupby('Order ID')['diff'].cumsum()
    

    编辑: 如果这还不够,您还可以在整个数据集上应用差异,而不是获取每个组的第一行。这也应该比以前的方法更快。

    idx_wo_first = df.index.difference(df.groupby('Order ID').head(1).index)
    df.loc[idx_wo_first, 'diff'] = df['Edit Date'].diff().loc[idx_wo_first] / np.timedelta64(1, 'D')
    df['sum'] = df.groupby('Order ID')['diff'].cumsum()
    

    【讨论】:

    • 我需要每个产品,所以每个组的第一行。你的第一个建议是黄金。谢谢,这个速度快多了。它一直在盯着我看。
    • 对不起,我不够清楚。我的两个代码都产生相同的输出(尽管第二个应该更快)。在第二个代码中,由于我在整个数据集上使用了 diff,因此每组的第一行是该组的第一行与最后一组的最后一行之间的差异,所以我需要将它们过滤掉。也请考虑接受我的回答,因为这正是您要找的。​​span>
    猜你喜欢
    • 2021-09-08
    • 2018-04-23
    • 1970-01-01
    • 2015-11-05
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    相关资源
    最近更新 更多