【问题标题】:Efficient way of aggregating previous(in time) rows聚合先前(及时)行的有效方法
【发布时间】:2021-04-16 14:31:29
【问题描述】:

我有以下不同客户在不同时间所下订单的数据框:

rng = list(pd.date_range('2019-02-24', periods=5, freq='T')) + list(pd.date_range('2019-03-
13', periods=2, freq='T')) + list(pd.date_range('2019-02-27', periods=1, freq='T'))
customers = ["12987"]*5 + ["89563"]*2 + ["56733"]
articles = ["8473", "7631", "1264", "8473", "5641", "9813", "7631", "1132"]

order_history = pd.DataFrame({'Customer_no': customers, 'Date': rng, 'Article_no': articles}) 
order_history

输出:

    Customer_no Date                    Article_no
0   12987       2019-02-24 00:00:00     8473
1   12987       2019-02-24 00:01:00     7631
2   12987       2019-02-24 00:02:00     1264
3   12987       2019-02-24 00:03:00     8473
4   12987       2019-02-24 00:04:00     5641
5   89563       2019-03-13 00:00:00     9813
6   89563       2019-03-13 00:01:00     7631
7   56733       2019-02-27 00:00:00     1132

我想为每个客户和行获取以前购买的文章。
预期输出:

    Customer_no Date                    Article_no  Previous_articles
0   12987       2019-02-24 00:00:00     8473        []
1   12987       2019-02-24 00:01:00     7631        [8473]
2   12987       2019-02-24 00:02:00     1264        [8473, 7631]
3   12987       2019-02-24 00:03:00     8473        [8473, 7631, 1264]
4   12987       2019-02-24 00:04:00     5641        [8473, 7631, 1264, 8473]
5   89563       2019-03-13 00:00:00     9813        []
6   89563       2019-03-13 00:01:00     7631        [9813]
7   56733       2019-02-27 00:00:00     1132        []

我意识到我可以使用 order_history.apply(lambda x: my_custom_function(x), axis=1) 之类的自定义函数遍历每一行 其中my_custom_function(x) 将针对每一行过滤整个order_history 以找到匹配的Customer_no 和适当的日期。我也意识到这个解决方案效率很低,因此希望有人有其他想法!

【问题讨论】:

    标签: python python-3.x pandas numpy pandas-groupby


    【解决方案1】:

    输入代码:

    import pandas as pd
    import numpy as np
    
    rng = list(pd.date_range('2019-02-24', periods=5, freq='T')) + list(pd.date_range('2019-03-13', periods=2, freq='T')) + list(pd.date_range('2019-02-27', periods=1, freq='T'))
    customers = ["12987"]*5 + ["89563"]*2 + ["56733"]
    articles = ["8473", "7631", "1264", "8473", "5641", "9813", "7631", "1132"]
    
    order_history = pd.DataFrame({'Customer_no': customers, 'Date': rng, 'Article_no': articles}) 
    order_history
    

    获取Previous_articles的代码:

    a = order_history['Article_no'].apply(lambda x: [] if pd.isnull(x) else [int(x)])
    order_history['Previous_articles'] = a.groupby(order_history['Customer_no']).apply(lambda x: x.cumsum())
    
    order_history["Previous_articles"] = order_history["Previous_articles"].apply(lambda x:x[:-1])
    order_history
    

    输出:

      Customer_no                Date Article_no         Previous_articles
    0       12987 2019-02-24 00:00:00       8473                        []
    1       12987 2019-02-24 00:01:00       7631                    [8473]
    2       12987 2019-02-24 00:02:00       1264              [8473, 7631]
    3       12987 2019-02-24 00:03:00       8473        [8473, 7631, 1264]
    4       12987 2019-02-24 00:04:00       5641  [8473, 7631, 1264, 8473]
    5       89563 2019-03-13 00:00:00       9813                        []
    6       89563 2019-03-13 00:01:00       7631                    [9813]
    7       56733 2019-02-27 00:00:00       1132                        []
    

    【讨论】:

    • 感谢您的巧妙解决方案!然而,即使解决方案是正确的,我也意识到我的问题比这更复杂一些。如果您能看看我的新问题,将不胜感激! stackoverflow.com/questions/65672290/…
    【解决方案2】:

    替代解决方案可能是使用自联接:

    df1 = df2 = order_history
    df = df1.merge(df2, on='Customer_no')
    df_ = df[df['Date_x']>= df['Date_y']]
    df_final = df_.groupby(['Customer_no', 'Date_x'])[['Article_no_y']].agg(list).reset_index()
    df_final['Previous_articles'] = df_final.Article_no_y.apply(lambda x: x[:-1] if len(x)>1 else [])
    df_final.rename(columns={'Date_x':'Date'}, inplace=True)
    df1.merge(df_final[['Customer_no', 'Date', 'Previous_articles']], on=['Customer_no', 'Date'])
    
    Which return: Customer_no                Date Article_no         Previous_articles
    0       12987 2019-02-24 00:00:00       8473                        []
    1       12987 2019-02-24 00:01:00       7631                    [8473]
    2       12987 2019-02-24 00:02:00       1264              [8473, 7631]
    3       12987 2019-02-24 00:03:00       8473        [8473, 7631, 1264]
    4       12987 2019-02-24 00:04:00       5641  [8473, 7631, 1264, 8473]
    5       89563 2019-03-13 00:00:00       9813                        []
    6       89563 2019-03-13 00:01:00       7631                    [9813]
    7       56733 2019-02-27 00:00:00       1132                        []
    

    【讨论】:

    • 感谢您的解决方案!然而,即使解决方案是正确的,我也意识到我的问题比这更复杂一些。如果您能看看我的新问题,将不胜感激! stackoverflow.com/questions/65672290/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 2023-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-12
    相关资源
    最近更新 更多