【问题标题】:How to group multiple dataframe colmuns year-wise?如何按年对多个数据框列进行分组?
【发布时间】:2021-06-25 02:52:30
【问题描述】:

我有一个房价数据集,其中包含区域名称和跨年份的月销售价格。我想做的是将所有这些月度数据汇总成年度数据,这样最后我就得到了年度销售数据。我尝试将每月列转换为 DataTime 索引并尝试在它们上应用 pd.Grouper 以聚合它们,但我无法让它们工作。

这是我的代码:

data1=pd.read_csv('zillow 1.csv')
col=data1.drop(columns=['RegionID', 'SizeRank', 'RegionName', 'RegionType', 'StateName']).columns # just to get all date-time columns.
for i in col:
    data1[i]=pd.to_datetime(data1[i],format=('%Y'))
data1.drop(columns=['RegionID', 'SizeRank',  'RegionType', 'StateName']) # just dropping other columns so that I am left with Region name and monthly figures.

g=data1.groupby(pd.Grouper(col,"Y))['RegionName'].sum()

当我执行这段代码时,它会抛出一个错误。 TypeError: __init__() got multiple values for argument 'freq'

为了清楚起见,这是我每月专栏的外观:

Index(['1996-01-31', '1996-02-29', '1996-03-31', '1996-04-30', '1996-05-31',
       '1996-06-30', '1996-07-31', '1996-08-31', '1996-09-30', '1996-10-31',
       ...
       '2020-05-31', '2020-06-30', '2020-07-31', '2020-08-31', '2020-09-30',
       '2020-10-31', '2020-11-30', '2020-12-31', '2021-01-31', '2021-02-28'],
      dtype='object', length=302)

有什么办法可以做到这一点吗?最终,我的目标是绘制这些年度明智的数字,以便我可以比较不同地区之间的销售情况。 Here 是数据集链接,如果有人感兴趣的话

【问题讨论】:

    标签: python-3.x pandas pandas-groupby


    【解决方案1】:

    由于您想按年份汇总列,我将这样做。

    第 1 步:从 df 中获取所有具有年份的列名。查看数据,这些列从iloc[5:]开始

    第 2 步:从集合中获取唯一年份。

    第 3 步:如果列名以年份开头,则使用 axis=1 按行求和

    import pandas as pd
    df = pd.read_csv('zillow.csv')
    
    years = sorted({yr[:4] for yr in df.columns[5:].values})
    
    for yr in years:
        df[yr] = df[[col for col in df.columns[5:] if col.startswith(yr)]].sum(axis=1)
    
    print (df)
    

    这个输出将是:

         RegionID  SizeRank  ...       2020       2021
    0      102001         0  ...  3059372.0   541886.0
    1      394913         1  ...  5894078.0  1036463.0
    2      753899         2  ...  8587321.0  1516642.0
    3      394463         3  ...  2991040.0   523830.0
    4      394514         4  ...  3142269.0   553460.0
    ..        ...       ...  ...        ...        ...
    907    394767       929  ...   909407.0   158436.0
    908    753874       930  ...  2351237.0   401301.0
    909    394968       931  ...  1607013.0   264483.0
    910    395188       932  ...   816467.0   137119.0
    911    394743       933  ...  3729067.0   636767.0
    

    这将为您提供如下所有列:

    >>> df.columns
    Index(['RegionID', 'SizeRank', 'RegionName', 'RegionType', 'StateName',
           '1996-01-31', '1996-02-29', '1996-03-31', '1996-04-30', '1996-05-31',
           ...
           '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020',
           '2021'],
          dtype='object', length=333)
    

    有了这些信息,您就可以按RegionID, SizeRank, RegionName, RegionType, StateName 分组。或按您想要的任何列。

    如果你想要 groupby RegionName 多年来,你可以这样做。

    years += ['RegionName']
    
    print (df[years].groupby(['RegionName']).sum())
    

    这个输出将是:

                        1996       1997       1998       1999       2000  \
    RegionName                                                             
    Aberdeen, SD         0.0        0.0        0.0        0.0        0.0   
    Aberdeen, WA         0.0        0.0        0.0        0.0        0.0   
    Abilene, TX          0.0        0.0        0.0        0.0        0.0   
    Ada, OK         533030.0   548855.0   586340.0   593326.0   615267.0   
    Adrian, MI      957140.0  1056303.0  1163536.0  1254465.0  1356705.0   
    ...                  ...        ...        ...        ...        ...   
    Youngstown, OH  870237.0   898081.0   930793.0   957257.0   990584.0   
    Yuba City, CA        0.0        0.0        0.0        0.0  1141184.0   
    Yuma, AZ             0.0        0.0   948628.0  1306891.0  1356049.0   
    Zanesville, OH  761127.0   774986.0   838063.0   881872.0   922311.0   
    Zapata, TX           0.0        0.0        0.0        0.0        0.0   
    
                         2001       2002       2003       2004       2005  \
    RegionName                                                              
    Aberdeen, SD          0.0        0.0        0.0        0.0  1087463.0   
    Aberdeen, WA          0.0        0.0        0.0        0.0  1323941.0   
    Abilene, TX           0.0        0.0        0.0        0.0  1070523.0   
    Ada, OK          642837.0   662776.0   684052.0   705584.0   740637.0   
    Adrian, MI      1426047.0  1463274.0  1495317.0  1582738.0  1666558.0   
    ...                   ...        ...        ...        ...        ...   
    Youngstown, OH  1033607.0  1064146.0  1089705.0  1124423.0  1162917.0   
    Yuba City, CA   1387296.0  1570888.0  1860855.0  2343419.0  2996582.0   
    Yuma, AZ        1379097.0  1421725.0  1481491.0  1634469.0  2050662.0   
    Zanesville, OH   981391.0  1002341.0  1037380.0  1091709.0  1137257.0   
    Zapata, TX            0.0        0.0        0.0        0.0   159482.0   
    
                         2006       2007       2008       2009       2010  \
    RegionName                                                              
    Aberdeen, SD    1293335.0  1375324.0  1437710.0  1451361.0  1462089.0   
    Aberdeen, WA    1545565.0  1654038.0  1619901.0  1491200.0  1373750.0   
    Abilene, TX     1153954.0  1222018.0  1240798.0  1235595.0  1226032.0   
    Ada, OK          773481.0   794686.0   794048.0   894670.0   934917.0   
    Adrian, MI      1705913.0  1660779.0  1548574.0  1417074.0  1313150.0   
    ...                   ...        ...        ...        ...        ...   
    Youngstown, OH  1177239.0  1164396.0  1140398.0  1073945.0  1014500.0   
    Yuba City, CA   3293180.0  2975985.0  2535911.0  2173688.0  2107412.0   
    Yuma, AZ        2468443.0  2467547.0  2203446.0  1867022.0  1694541.0   
    Zanesville, OH  1180517.0  1224656.0  1212803.0  1167160.0  1146663.0   
    Zapata, TX       666839.0   704868.0   749365.0   725521.0   717505.0   
    
                         2011       2012       2013       2014       2015  \
    RegionName                                                              
    Aberdeen, SD    1476833.0  1508806.0  1572832.0  1643632.0  1704464.0   
    Aberdeen, WA    1287545.0  1275520.0  1335709.0  1415693.0  1543013.0   
    Abilene, TX     1184050.0  1210285.0  1238084.0  1308606.0  1342747.0   
    Ada, OK          924909.0   965829.0   981066.0   970680.0  1001622.0   
    Adrian, MI      1250472.0  1237695.0  1285864.0  1352536.0  1427238.0   
    ...                   ...        ...        ...        ...        ...   
    Youngstown, OH   966189.0   942388.0   950965.0   944779.0   960177.0   
    Yuba City, CA   2016705.0  2029500.0  2279999.0  2502882.0  2565389.0   
    Yuma, AZ        1441573.0  1387678.0  1455966.0  1551797.0  1595309.0   
    Zanesville, OH  1116737.0  1114035.0  1128231.0  1166683.0  1209147.0   
    Zapata, TX       693401.0   725566.0   759697.0   818673.0   893575.0   
    
                         2016       2017       2018       2019       2020  \
    RegionName                                                              
    Aberdeen, SD    1791782.0  1898902.0  1994661.0  2060803.0  2093338.0   
    Aberdeen, WA    1703247.0  1855551.0  2073542.0  2290696.0  2623661.0   
    Abilene, TX     1418761.0  1474377.0  1556264.0  1623550.0  1684742.0   
    Ada, OK         1073328.0  1105749.0  1169043.0  1151188.0  1223348.0   
    Adrian, MI      1525827.0  1657855.0  1750303.0  1829592.0  1925909.0   
    ...                   ...        ...        ...        ...        ...   
    Youngstown, OH   989771.0  1050918.0  1109259.0  1154718.0  1232026.0   
    Yuba City, CA   2753120.0  3080021.0  3367719.0  3551897.0  3778631.0   
    Yuma, AZ        1634934.0  1739666.0  1832909.0  1903329.0  2063665.0   
    Zanesville, OH  1248745.0  1307947.0  1379258.0  1470346.0  1565903.0   
    Zapata, TX       948207.0  1016711.0  1049410.0  1096617.0  1117857.0   
    
                        2021  
    RegionName                
    Aberdeen, SD    354763.0  
    Aberdeen, WA    495262.0  
    Abilene, TX     296703.0  
    Ada, OK         209543.0  
    Adrian, MI      336499.0  
    ...                  ...  
    Youngstown, OH  224846.0  
    Yuba City, CA   674837.0  
    Yuma, AZ        379388.0  
    Zanesville, OH  260520.0  
    Zapata, TX      193910.0  
    
    [912 rows x 26 columns]
    

    【讨论】:

    • 感谢您的回答,基本上您只是按行汇总所有月份的价格,对吧?
    • 是的,这就是你想要做的。我只是向您展示了一种更简单的方法
    • 您现在可以通过 groupby(Region) 来获取年份。如果您使用 agg() 您可以对该区域的每一列求和。如果您也需要解决方案,请告诉我,我可以扩展它以向您展示解决方案的那部分
    • 我更新了答案,按年份给你分组。
    • 谢谢,我只是在尝试如何在 group by 中保留 RegionName 列
    【解决方案2】:

    首先将melt() 的所有日期列分成一个Date 和一个Price 列:

    data1 = pd.read_csv('zillow 1.csv')
    data1 = data1.melt(
        id_vars=['RegionID', 'SizeRank', 'RegionName', 'RegionType', 'StateName'], 
        var_name='Date',
        value_name='Price')
    

    转换Dateto_datetime()(以便我们以后可以访问Date.dt.year):

    data1.Date = pd.to_datetime(data1.Date)
    

    然后groupby()RegionNameDate.dt.year 并采取分组sum()

    data1 = data1.groupby(['RegionName', data1.Date.dt.year])[['Price']].sum()
    
    #          RegionName  Date      Price
    # 0      Aberdeen, SD  1996        0.0
    # 1      Aberdeen, SD  1997        0.0
    # 2      Aberdeen, SD  1998        0.0
    # 3      Aberdeen, SD  1999        0.0
    # 4      Aberdeen, SD  2000        0.0
    # ...             ...   ...        ...
    # 23707    Zapata, TX  2017  1016711.0
    # 23708    Zapata, TX  2018  1049410.0
    # 23709    Zapata, TX  2019  1096617.0
    # 23710    Zapata, TX  2020  1117857.0
    # 23711    Zapata, TX  2021   193910.0
    

    【讨论】:

    • 感谢这种方法,我从来没有意识到我也可以使用这样的东西
    猜你喜欢
    • 2021-09-26
    • 2022-01-22
    • 2019-04-17
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 2020-03-22
    • 1970-01-01
    • 2021-05-06
    相关资源
    最近更新 更多