Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在当前行日期之前与组的平均值_Python_Pandas - Fatal编程技术网

Python 在当前行日期之前与组的平均值

Python 在当前行日期之前与组的平均值,python,pandas,Python,Pandas,我有一个熊猫数据框,如下所示 df = pd.DataFrame([['John', '1/1/2017','10'], ['John', '2/2/2017','15'], ['John', '2/2/2017','20'], ['John', '3/3/2017','30'], ['Sue', '1/1/2017','10'],

我有一个熊猫数据框,如下所示

df = pd.DataFrame([['John', '1/1/2017','10'],
                   ['John', '2/2/2017','15'],
                   ['John', '2/2/2017','20'],
                   ['John', '3/3/2017','30'],
                   ['Sue', '1/1/2017','10'],
                   ['Sue', '2/2/2017','15'],
                   ['Sue', '3/2/2017','20'],
                   ['Sue', '3/3/2017','7'],
                   ['Sue', '4/4/2017','20']
                  ],
                   columns=['Customer', 'Deposit_Date','DPD'])
。在下面的屏幕截图中,计算PreviousMean列的最佳方法是什么

该列是该客户的DPD的年迄今平均值。一、 e.包括所有DPD,但不包括与当前存款日期匹配的行。如果不存在以前的记录,则为null或0

屏幕截图:

注意事项:

  • 数据按客户名称分组,并按存款日期展开
  • 在每个组中,仅使用前几行中的值计算扩展平均值
  • 在每个新客户开始时,平均值为0或为空,因为之前没有形成平均值的记录
  • 数据框架按客户名称和存款日期订购

    • 这里有一种方法可以从平均计算中排除重复天数:

      # create helper series which is NaN for repeated days, DPD otherwise
      s = df.groupby(['Customer Name', 'Deposit_Date']).cumcount() == 1
      df['DPD2'] = np.where(s, np.nan, df['DPD'])
      
      # apply pd.expanding_mean
      df['CumMean'] = df.groupby(['Customer Name'])['DPD2'].apply(lambda x: pd.expanding_mean(x))
      
      # drop helper series
      df = df.drop('DPD2', 1)
      
      print(df)
      
        Customer Name Deposit_Date  DPD  CumMean
      0          John   01/01/2017   10     10.0
      1          John   01/01/2017   10     10.0
      2          John   02/02/2017   20     15.0
      3          John   03/03/2017   30     20.0
      4           Sue   01/01/2017   10     10.0
      5           Sue   01/01/2017   10     10.0
      6           Sue   02/02/2017   20     15.0
      7           Sue   03/03/2017   30     20.0
      

      不要分组和扩展平均值,而是根据条件过滤数据帧,并计算
      DPD的平均值

      • Customer
        ==当前行的
        Customer
      • 存款日期
        <当前行的
        存款日期
      使用
      df.apply
      对数据帧中的所有行执行此操作:

      df['PreviousMean'] = df.apply(
          lambda x: df[(df.Customer == x.Customer) & (df.Deposit_Date < x.Deposit_Date)].DPD.mean(), 
      axis=1)
      

      好的,这是迄今为止我提出的最好的解决方案

      诀窍是首先在customer&deposit date级别创建一个包含移动平均值的聚合表。要计算这意味着您必须先计算总和和计数

      s=df.groupby(['Customer Name','Deposit_Date'],as_index=False)[['DPD']].agg(['count','sum'])
      s.columns = [' '.join(col) for col in s.columns]
      s.reset_index(inplace=True)
      
      s['DPD_CumSum']=s.groupby(['Customer Name'])[['DPD sum']].cumsum()
      s['DPD_CumCount']=s.groupby(['Customer Name'])[['DPD count']].cumsum()
      s['DPD_CumMean']=s['DPD_CumSum']/ s['DPD_CumCount']
      s['DPD_PrevMean']=s.groupby(['Customer Name'])['DPD_CumMean'].shift(1)
      
      df=df.merge(s[['Customer Name','Deposit_Date','DPD_PrevMean']],how='left',on=['Customer Name','Deposit_Date'])
      

      谢谢-这并不能实现仅基于当前行之前的日期进行计算的效果,尽管前两行应该显示0或null。不过,我会仔细研究一下,看看它是否能让我有所收获。@user1761806,当然,我可能不完全理解你的问题。您可能需要为每个组包含DPD=0行,才能使其按您的需要工作。是的,我是这样做的。在我的例子中,10=平均值(10,10)和13.3=平均值(10,10,20)第三个假设是不正确的,但我选择了一个坏例子是错误的。零只是一个新客户的开始,反映了一个事实,即没有以前的记录来形成平均值。或者,它们可以为空。@user1761806,请更新您的示例数据和预期输出,因为还不清楚您试图实现什么。存款日期是否在新客户记录的开始处?如果没有,那么我认为,
      df['YTD\u DPD\u Mean']=df.groupby(['Customer Name']).apply(lambda x:x.shift().expansing().Mean())
      就是您所需要的一切,您已经按照要求进行了更新。我现在仍在做这件事,并在尝试其他东西。@user1761806,请用文本替换屏幕截图。请参阅此链接了解如何询问“确定”。我已按照链接中的建议,并提供了熊猫代码来生成玩具数据集。仅从链接重新发布答案:
      s=df.groupby(['Customer Name','Deposit_Date'],as_index=False)[['DPD']].agg(['count','sum'])
      s.columns = [' '.join(col) for col in s.columns]
      s.reset_index(inplace=True)
      
      s['DPD_CumSum']=s.groupby(['Customer Name'])[['DPD sum']].cumsum()
      s['DPD_CumCount']=s.groupby(['Customer Name'])[['DPD count']].cumsum()
      s['DPD_CumMean']=s['DPD_CumSum']/ s['DPD_CumCount']
      s['DPD_PrevMean']=s.groupby(['Customer Name'])['DPD_CumMean'].shift(1)
      
      df=df.merge(s[['Customer Name','Deposit_Date','DPD_PrevMean']],how='left',on=['Customer Name','Deposit_Date'])