代码之家  ›  专栏  ›  技术社区  ›  JAG2024

pandas数据框中的Groupby特定月份和总和值

  •  0
  • JAG2024  · 技术社区  · 8 年前

    我有一个数据帧 df 看起来是这样的,没有设置索引:

    df.head()

        year    month   inch    mm
    0   1981    2       0.00    0.000
    1   1981    3       4.82    122.428
    2   1981    4       6.45    163.830
    3   1981    5       5.03    127.762
    4   1981    6       1.25    31.750
    

    (1) 首先,我只想选择1987年到2017年之间的年份。

    (2) 然后我想按年份对所选月份进行分组:MAM(so 3-5)、JJAS(6-9)和OND(10-12),并对 mm 这几个月的专栏。

    结果可能如下:

    year   season   mm
    1981   MAM      360
    1981   JJAS     167
    ...
    

    我不确定如何完成第1部分,但我知道对于第2部分,我需要转换 month

    然后我将通过以下方式定义兴趣月份:

    MAM = df.iloc[df.index.month.isin(np.r_[3:6])]
    JJAS = df.iloc[df.index.month.isin(np.r_[6:10])]
    OND = df.iloc[df.index.month.isin(np.r_[10:13])]
    

    但现在我得到了错误 AttributeError: 'RangeIndex' object has no attribute 'month'

    提前感谢!

    2 回复  |  直到 6 年前
        1
  •  1
  •   cs95 abhishek58g    8 年前

    第一部分相当简单。使用 pd.Series.between :

    df = df[df.year.between(1987, 2017)]
    

    如果 year 未排序,我建议排序 df sort_values(subset='year') 这样做。

    对于下一部分,一个解决方案将涉及生成 dict 映射,然后使用 map 转换的步骤 month 到映射的字符串,并在该字符串上分组。

    mapping = {3 : 'MAM', 4 : 'MAM', 5 : 'MAM', 6 : 'JJAS' ,... } # complete this
    r = df.groupby(['year', df.month.map(mapping)]).sum()
    
        2
  •  1
  •   andrew_reece    8 年前

    year month 建立索引,然后 groupby() 使用自定义项。

    示例数据:

    N = 10
    years = pd.date_range("1981", "2017", freq="A").year
    dates = np.random.choice(years, size=N, replace=True)
    months = np.random.choice(range(1,13), size=N, replace=True)
    inches = np.random.randint(1,20, size=N)
    mm = np.random.randint(1,100, size=N)
    data = {"year":dates, "month":months, "inch":inches, "mm":mm}
    df = pd.DataFrame(data)
    
    df
       inch  mm  month  year
    0    19  31     12  1990
    1     8  71      9  1986
    2     5  85      2  2009
    3    17   8     12  2005
    4    10  14     12  1987
    5     7  87      2  1982
    6     8  59      2  2004
    7     8  74      8  2016
    8     5   6      6  1993
    9     3   7     12  1982
    

    mask = df.year.between(1987, 2017)
    df.index = df.apply(lambda x: pd.to_datetime("{0} {1}".format(x.year, x.month), 
                                                 format="%Y %m"), axis=1)
    

    然后使用groupby 和一个分月功能:

    def month_gb(x):
        if x.month in range(3,6):
            return 'MAM'
        elif x.month in range(6,10):
            return 'JJAS'
        elif x.month in range(10,13):
            return 'OND'
    
    df.loc[mask].groupby(["year", month_gb]).mm.sum()
    
    year      
    1987  OND     14
    1990  OND     31
    1993  JJAS     6
    2005  OND      8
    2016  JJAS    74
    Name: mm, dtype: int64