【问题标题】:Groupby max and min value of each month over the yearsGroupby多年来每个月的最大值和最小值
【发布时间】:2023-04-10 22:15:02
【问题描述】:

我正在尝试绘制一个图表,显示 2005-2014 年期间的每日最高和最低温度。 Data_Value 列中表示温度。

我很难弄清楚如何在这里进行。我需要以月而不是年或日显示 x 轴。

数据集

                     ID Element  Data_Value
Date                                       
2005-01-01  USW00004848    TMIN           0
2005-01-01  USC00207320    TMAX         150
2005-01-01  USC00207320    TMIN         -11
2005-01-01  USW00014833    TMIN         -44
2005-01-01  USW00014833    TMAX          33
.....                                     
2015-12-31  USC00200032    TMAX          11
2015-12-31  USC00205050    TMIN         -17
2015-12-31  USC00208202    TMAX           0
2015-12-31  USC00201250    TMIN          -6
2015-12-31  USC00200230    TMIN         -17

我的尝试:

  1. 分别从数据集中提取 TMAX 和 TMIN
dfMax = df2[df2["Element"] == "TMAX"] 
dfMin = df2[df2["Element"] == "TMIN"]
  1. 查找每日最大值和最小值
dfMinD = dfMin.Data_Value.resample("d").min()
dfMaxD = dfMax.Data_Value.resample("d").max()

我被困在这里了。该图在 x 轴上显示年份而不是月份。

我认为我需要按月查找最高和最低温度?如何按月对它们进行分组以显示 2005 年至 2014 年期间每个月(1 月至 12 月)的每日最大值和最小值?

【问题讨论】:

    标签: python pandas matplotlib plot python-datetime


    【解决方案1】:

    第一个解决方案是在月份开始时将 d 更改为 MS

    dfMax = df2[df2["Element"] == "TMAX"] 
    dfMin = df2[df2["Element"] == "TMIN"]
    
    dfMinD = dfMin.Data_Value.resample("MS").min()
    dfMaxD = dfMax.Data_Value.resample("MS").max()
    
    df = pd.concat([dfMaxD, dfMinD], axis=1, keys=('max','min'))
    

    另一种解决方案,将DatetimeIndex.to_period 传递给DataFrame.groupby 并聚合minmax

    dfMax = df2[df2["Element"] == "TMAX"] 
    dfMin = df2[df2["Element"] == "TMIN"]
    
    dfMaxD = dfMax.groupby(dfMax.index.to_period('m'))['Data_Value'].max()
    dfMinD = dfMin.groupby(dfMin.index.to_period('m'))['Data_Value'].min()
    
    print (dfMinD)
    Date
    2005-01   -44
    2015-12   -17
    Freq: M, Name: Data_Value, dtype: int64
    
    print (dfMaxD)
    Date
    2005-01    150
    2015-12     11
    Freq: M, Name: Data_Value, dtype: int64
    
    df = pd.concat([dfMaxD, dfMinD], axis=1, keys=('max','min'))
    print (df)
             max  min
    Date             
    2005-01  150  -44
    2015-12   11  -17
    

    或者如果需要一个解决方案,首先创建月份 PeriodIndex,然后通过 Series.unstack 重塑并按第一级聚合 minmax 分组:

    df = (df2.set_index(df2.index.to_period('m'))
             .set_index(['ID','Element'], append=True)['Data_Value']
             .unstack()
             .groupby(level=0)
             .agg({'TMAX':'max', 'TMIN':'min'}))
    print (df)
              TMAX  TMIN
    Date                
    2005-01  150.0 -44.0
    2015-12   11.0 -17.0
    

    【讨论】:

    • 它就像一个魅力!谢谢!感谢您对 DatetimeIndex.to_period 的引用,每天都能学到新东西!
    【解决方案2】:
    #df.reset_index(inplace=True) #if date is the index
    dfMax=df[df['Element'].eq('TMAX')]
    dfMin=df[df['Element'].eq('TMIN')]
    

    每个月不考虑年份,使用groupby + Series.dt.month

    dfMonths_max=dfMax.groupby(df['Date'].dt.month)['Data_Value'].max()
    dfMonths_min=dfMin.groupby(df['Date'].dt.month)['Data_Value'].min()
    

    print(dfMonths_max)
    Date
    1     150
    12     11
    Name: Data_Value, dtype: int64
    

    print(dfMonths_min)
    Date
    1    -44
    12   -17
    Name: Data_Value, dtype: int64
    

    每年使用resample

    dfMonths_by_age_max=dfMax.resample('M',on='Date')['Data_Value'].max()
    dfMonths_by_age_min=dfMin.resample('M',on='Date')['Data_Value'].min()
    

    print(dfMonths_by_age_max)
    
    Date
    2005-01-31    150.0
    2005-02-28      NaN
    2005-03-31      NaN
    2005-04-30      NaN
    2005-05-31      NaN
                  ...  
    2015-08-31      NaN
    2015-09-30      NaN
    2015-10-31      NaN
    2015-11-30      NaN
    2015-12-31     11.0
    Freq: M, Name: Data_Value, Length: 132, dtype: float64
    

    print(dfMonths_by_age_min)
    
    
    Date
    2005-01-31   -44.0
    2005-02-28     NaN
    2005-03-31     NaN
    2005-04-30     NaN
    2005-05-31     NaN
                  ... 
    2015-08-31     NaN
    2015-09-30     NaN
    2015-10-31     NaN
    2015-11-30     NaN
    2015-12-31   -17.0
    Freq: M, Name: Data_Value, Length: 132, dtype: float64
    

    【讨论】:

    • 感谢您花时间帮助解决此问题。尝试了您的解决方案,它也有效!
    猜你喜欢
    • 2016-09-18
    • 2023-03-23
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-07
    • 1970-01-01
    • 2021-01-19
    相关资源
    最近更新 更多