【问题标题】:Calculate value difference using min and max dates使用最小和最大日期计算值差
【发布时间】:2021-12-17 00:49:13
【问题描述】:

我正在尝试使用最小日期和最大日期来计算价值增长/下降。我的数据目前如下所示:

    Code      Date        Value
0   A         2020-12-31  80122.0
1   A         2019-12-31  45472.0
2   A         2018-12-31  31917.0
3   A         2017-12-31  23432.0
4   B         2020-12-31      0.0

对于代码 A,我需要保留最大 (2020-12-31) 和最小 (2017-12-31) 日期以及值,以便稍后计算差异。我有多个代码,需要能够对每个代码应用相同的逻辑。有关解决此问题的最佳方法的任何建议?

谢谢

【问题讨论】:

  • df.groupby('Code')['Date'].agg(['min','max'])。但是你需要计算日期或价值的差异吗?
  • 感谢Quang,旨在计算Value的差异。所以 A 是 56690。
  • 非常感谢 - 这给了我需要的结果。
  • 您对 SO 并不陌生,所以您现在应该知道了。提供一些实际代码,以便我们更轻松地为您提供帮助。 from io import StringIOdf = pd.read_csv(StringIO(df_str), sep="\s+")(复制粘贴你的代码)

标签: python pandas


【解决方案1】:

在您的情况下,您想对日期进行排序,然后是 groupby 并首先提取,最后:

 df.sort_values(['Code','Date']).groupby('Code')['Value'].agg(['first','last'])

输出:

        first     last
Code                  
A     23432.0  80122.0
B         0.0      0.0

【讨论】:

    【解决方案2】:

    我会先sort_values 然后你可以在“代码”上drop_duplicates。对keep 使用不同的逻辑,这使您可以获取每个“代码”中的第一行和最后一行(基于日期),然后您可以将其减去以获得每个代码的日期差异和值差异。

    df = df.sort_values(['Code', 'Date'])
    
    (df.drop_duplicates('Code', keep='last').set_index('Code')
     - df.drop_duplicates('Code', keep='first').set_index('Code'))
    
    #          Date    Value
    #Code                   
    #A    1096 days  56690.0
    #B       0 days      0.0
    

    或者,如果您不仅需要差异并且实际上需要行,那么我会将 concat 放在一起而不是减去。避免.first聚合的主要原因是因为它does not guarantee data come from the same rows(没有指定dropna)在空值的情况下。

    pd.concat([df.drop_duplicates('Code', keep='last').set_index('Code'),
               df.drop_duplicates('Code', keep='first').set_index('Code')],
              keys=['Last', 'First'], axis=1)
    
    #           Last               First         
    #           Date    Value       Date    Value
    #Code                                        
    #A    2020-12-31  80122.0 2017-12-31  23432.0
    #B    2020-12-31      0.0 2020-12-31      0.0
    

    【讨论】:

      【解决方案3】:

      自从你

      需要保留最大 (2020-12-31) 和最小 (2017-12-31) 日期以及值...

      ,你可以试试:

      df = pd.DataFrame({'Code':['A','A','A','A','B'], 
                         'Date': ['2020-12-31', '2019-12-31', '2018-12-31', '2017-12-31', '2020-12-31'],
                         'Value': [80122.0, 45472.0, 31917.0, 23432.0, 0.0] 
                        }, )
      
      df.loc[:, 'Date'] = pd.to_datetime(df.loc[:, 'Date'])
      

      是提到的df:

          Code    Date    Value
      0   A   2020-12-31  80122.0
      1   A   2019-12-31  45472.0
      2   A   2018-12-31  31917.0
      3   A   2017-12-31  23432.0
      4   B   2020-12-31  0.0
      

      所以另一种方式可以是:

      dictionary = {}
      
      for code in df.loc[:, 'Code'].unique():
          dictionary[code] = {'Date min': df.loc[df.loc[:, 'Code']==code,'Date'].min(),
                              'Value min': df.loc[(df.loc[:, 'Code']==code)& (df.loc[:,'Date'] == df.loc[df.loc[:, 'Code']==code,'Date'].min()), 'Value'].values[0],
                              'Date max': df.loc[df.loc[:, 'Code']==code,'Date'].max(),
                              'Value max':df.loc[(df.loc[:, 'Code']==code)&(df.loc[:,'Date'] == df.loc[df.loc[:, 'Code']==code,'Date'].max()), 'Value'].values[0]
                                           
                             }
      resume = pd.DataFrame(dictionary)
      resume = resume.transpose()
      resume
      

      输出:

          Date min    Value min   Date max    Value max
      A   2017-12-31  23432.0   2020-12-31    80122.0
      B   2020-12-31  0.0       2020-12-31    0.0
      

      【讨论】:

        猜你喜欢
        • 2019-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-12
        • 1970-01-01
        • 2015-06-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多