每行以日期为条件的熊猫数据框平均值

时间:2019-10-03 17:17:11

标签: python pandas date conditional-statements mean

在带有项目数据(输入表)的熊猫数据框中,我试图计算每行“成功”的历史平均值。条件是:

  1. 仅考虑与计算所得行具有相同“客户”的项目
  2. 仅考虑在计算行中项目的“开始日期”之前带有“结束日期”的项目
  3. 如果没有以某个特定客户结束的项目,则应返回空白

任何帮助都非常感谢,因为我不知道从哪里开始。谢谢。

输入表

Project ID    Start Date    End Date    Success Customer Name
8403986       3/13/2015     9/9/2015    0.396   ENGINEERING INC
92083597      6/20/2016     12/24/2016  0.3     ENGINEERING INC
13979865      3/18/2019     5/5/2019    0.2004  ENGINEERING INC
93106418      1/22/2017     11/6/2017   0.374   MANAGEMENT CORP
3658851       8/5/2018      12/17/2018  0.5002  SERVICES INC
116547576     10/31/2015    12/30/2015  0.478   MANAGEMENT CORP
4164070       10/2/2018     10/12/2018  0.5     ENGINEERING INC
49701600      12/23/2017    10/1/2018   0.226   MANAGEMENT CORP
6235002       9/27/2016     4/25/2017   0.542   MANAGEMENT CORP
54113980      10/27/2015    1/2/2016    0.344   ENGINEERING INC
104596325     7/3/2015      2/17/2016   0.455   MANAGEMENT CORP 
69580391      8/9/2016      1/10/2017   0.39    ENGINEERING INC
111382294     1/13/2017     10/18/2017  0.299   SERVICES INC
7904360       12/12/2015    3/16/2016   0.281   MANAGEMENT CORP
117003225     5/5/2017      5/12/2017   0.2868  SERVICES INC
99819795      10/9/2015     1/14/2016   0.356   ENGINEERING INC
122919691     1/16/2016     10/24/2016  0.474   SERVICES INC

输出表

Project ID    Start Date    End Date    Success Customer Name    Historic Success
8403986       3/13/2015     9/9/2015    0.396   ENGINEERING INC  
92083597      6/20/2016     12/24/2016  0.3     ENGINEERING INC  0.365
13979865      3/18/2019     5/5/2019    0.2004  ENGINEERING INC  0.381
93106418      1/22/2017     11/6/2017   0.374   MANAGEMENT CORP  0.405
3658851       8/5/2018      12/17/2018  0.5002  SERVICES INC     0.353
116547576     10/31/2015    12/30/2015  0.478   MANAGEMENT CORP  
4164070       10/2/2018     10/12/2018  0.5     ENGINEERING INC  0.357
49701600      12/23/2017    10/1/2018   0.226   MANAGEMENT CORP  0.439
6235002       9/27/2016     4/25/2017   0.542   MANAGEMENT CORP  0.405
54113980      10/27/2015    1/2/2016    0.344   ENGINEERING INC  0.396
104596325     7/3/2015      2/17/2016   0.455   MANAGEMENT CORP  
69580391      8/9/2016      1/10/2017   0.39    ENGINEERING INC  0.365
111382294     1/13/2017     10/18/2017  0.299   SERVICES INC     0.474
7904360       12/12/2015    3/16/2016   0.281   MANAGEMENT CORP  
117003225     5/5/2017      5/12/2017   0.2868  SERVICES INC     0.474
99819795      10/9/2015     1/14/2016   0.356   ENGINEERING INC  0.396
122919691     1/16/2016     10/24/2016  0.474   SERVICES INC     

例如项目'92083597'与'工程技术公司'与'开始日期'= 6/20/2016

条件1:仅考虑“客户” = Engineering INC的行

Project ID    Start Date    End Date    Success Customer Name    
8403986       3/13/2015     9/9/2015    0.396   ENGINEERING INC  
92083597      6/20/2016     12/24/2016  0.3     ENGINEERING INC  
13979865      3/18/2019     5/5/2019    0.2004  ENGINEERING INC  
4164070       10/2/2018     10/12/2018  0.5     ENGINEERING INC  
54113980      10/27/2015    1/2/2016    0.344   ENGINEERING INC  
69580391      8/9/2016      1/10/2017   0.39    ENGINEERING INC  
99819795      10/9/2015     1/14/2016   0.356   ENGINEERING INC  

条件2:仅考虑2016年6月20日之前具有“结束日期”的行

Project ID    Start Date    End Date    Success Customer Name    
8403986       3/13/2015     9/9/2015    0.396   ENGINEERING INC  
54113980      10/27/2015    1/2/2016    0.344   ENGINEERING INC  
99819795      10/9/2015     1/14/2016   0.356   ENGINEERING INC  

其余三行(0.369 + 0.344 + 0.356)/ 3的平均值为 0.365 。 这将被返回,这是行项目“ 92083597”的“历史性成功”。 如果在第一个或第二个条件之后没有剩余项目,则返回空白。

1 个答案:

答案 0 :(得分:2)

如果您真的想学习解决方法,则应将此问题分解为多个子问题。这将帮助您成为一名优秀的程序员,并让您获得各种堆栈溢出答案的点点滴滴。此外,您还应在列名中避免使用空格

这是我要这样做的方式,但可能会有更快的方法

首先,您应该按日期对数据框进行排序,确保您的数据格式正确。您可以使用下面的代码来帮助确保其正确排序。它首先确保该列的格式正确,然后根据Customer_Name进行排序以将它们分组在一起,然后根据日期进行排序以组织项目

df['End_Date'] =pd.to_datetime(df["End_Date"])
df = df.sort_values(["Customer_Name", "End_Date"])

然后根据先前的成功率计算每个公司的平均值。为此,您必须计算熊猫的移动平均值。这可以通过使用循环来完成,但是在Pandas中通常有一种更快的方法。

df.groupby("Customer_Name").Success.expanding().mean()

这将按日期顺序生成每个Customer_Name的运行平均值。完整的代码在下面。您应该尝试查看我创建的每个子问题,看看是否可以使解决方案更好,或者添加更多您可能需要的子问题。

df['End_Date'] =pd.to_datetime(df["End_Date"])
df = df.sort_values(["Customer_Name", "End_Date"])
df["Historic_Success"] = df.groupby("Customer_Name")
                       .Success
                       .expanding()
                       .mean()
                       .values  

希望能回答您的问题。如果您想将数据框重新排序为原来的格式,则可以按索引排序,因为我尚未在代码中重新索引该数据框。

编辑: 为了避免历史成功中出现首次成功率,您可以在扩展函数中添加输入“ 2”。

df["Historic_Success"] = df.groupby("Customer_Name")
                       .Success
                       .expanding(2)
                       .mean()
                       .values  

但这仍将包括当前项目的成功率。这意味着项目1的历史成功率将是项目1和项目2的成功率的平均值。

要避免这种情况,最好的避免方法是使用下面的代码。

df["Historic_Success"] = df.groupby("Customer_Name").Success.shift(1)
df.Historic_Success = df.groupby("Customer_Name")
                       .Historic_Success
                       .expanding()
                       .mean()
                       .values  

在这里,将数据组织成客户名称和日期之后,将成功数据向下移动1。然后,对已移动的数据运行同一行代码。