Python 从dataframe中的特定列开始,计算每4列的平均值,并将每个平均值结果输出到np数组进行进一步处理

Python 从dataframe中的特定列开始,计算每4列的平均值,并将每个平均值结果输出到np数组进行进一步处理,python,numpy,dataframe,Python,Numpy,Dataframe,这里需要您的帮助,了解如何计算每行每4列的平均值,并将平均值输出到numpy数组 df = pd.read_excel (open(excel_path,'rb'), skiprows= 5, skipfooter= 27) 我使用pandas readexcel在数据框中导入excel数据,如下所示: Variable 2003 4Q 2004 1Q 2004 2Q 2004 3Q 2004 4Q ....... 2020 1Q 0 A

这里需要您的帮助,了解如何计算每行每4列的平均值,并将平均值输出到numpy数组

df = pd.read_excel (open(excel_path,'rb'), skiprows= 5, skipfooter= 27)
我使用pandas readexcel在数据框中导入excel数据,如下所示:

   Variable  2003 4Q          2004 1Q   2004 2Q     2004 3Q    2004 4Q  ....... 2020 1Q
0  A         unwanted_value1  913614    921129      924066     942764     
1  B         unwanted_value2  49757     51065.7     52029.2    51213.1     
2  C         unwanted_value3  19255.4   19152.5     18857      16825     
3  D         unwanted_value4  na        na          na         na    
4  E         unwanted_value5  25092.1   26505.2     27760      28604.6   
5  F         unwanted_value6  863857    870063      872037     891551   
如您所见,有两个问题:

  • 数据的某些部分不完整(例如,2003年只有第四季度的结果),我需要排除它们

  • 某些行中有“na”值

  • 我很难将.mean和.iloc组合起来

    df.平均值(轴=0,skipna=真,级别=无,仅数值=无)

    我尝试使用计数器跟踪每4个结果,并使用列索引指示要开始计算的列

    例如,我将值3赋给column_index,我认为这将使计算从2004 1Q开始,然后将df.iloc[column_index]馈送给df.mean方法。然而,对于如何将它们结合在一起,我有点困惑

    此外,该方法还必须考虑在特定列索引处停止的方法

    counter = 0 # counts every 4 result and reset again.
    column_index = 3
    
    while True:
    
        if counter != 4:
    
               #code need to calculate the average of the quarterly result using column index and output to numpy array.
              column_index += 4
               counter += counter
    
        elif counter == 4:
             counter = 0
            
    return()
    
    用于进一步处理的所需numpy阵列:

    [average_for_2004  average_for_2005 average_for_2006 average_for_2007 .....]
    
    请浏览至网站末尾,点击“新加坡外债统计(期末)、季度”链接,进入网站进行excel文件导出(需要选择导出为.xlsx,弹出窗口阻止程序暂时禁用,以便出现下载对话框): 试试这个:

    valid_years = [y.split("_")[0] for y in df.columns if y.endswith("_Q1") | y.endswith("_Q2") | y.endswith("_Q3") | y.endswith("_Q4")]
    valid_years = [x for x in set(valid_years) if valid_years.count(x)==4]
    
    results = {}
    for year in valid_years:
        results[year] = df.filter(regex='^'+str(year), axis=1).unstack().astype(float).mean(skipna=True)
    
    print(results)
    

    首先分离要聚合的列(从2004年第1季度开始的所有列):

    然后生成分组字典:

    grpDct = { t: t.split(' ')[0] for t in df2.columns }
    
    它将连续4列的范围映射到组

    实际计算包括:

    • 按上述词典(水平)分组
    • 计算每组的平均值
    • 将df的第一列与上面的分组连接起来
    执行此操作的代码是:

    result = df[['Variable']].join(df2.groupby(grpDct, axis=1).mean())
    
    对于我的样本数据(限于2003年、2004年和2005年),结果是:

      Variable        2004        2005
    0        A  925393.250  572893.250
    1        B   54266.250   36841.250
    2        C   18522.475   11722.475
    3        D         NaN     325.000
    4        E   26990.475   12840.475
    5        F  874377.000  466827.000
    
    array([[9.2539325e+05, 5.7289325e+05],
           [5.4266250e+04, 3.6841250e+04],
           [1.8522475e+04, 1.1722475e+04],
           [          nan, 3.2500000e+02],
           [2.6990475e+04, 1.2840475e+04],
           [8.7437700e+05, 4.6682700e+05]])
    
    或者只使用分组,而不使用变量列(和 转换为Numpy数组):

    这一次的结果是:

      Variable        2004        2005
    0        A  925393.250  572893.250
    1        B   54266.250   36841.250
    2        C   18522.475   11722.475
    3        D         NaN     325.000
    4        E   26990.475   12840.475
    5        F  874377.000  466827.000
    
    array([[9.2539325e+05, 5.7289325e+05],
           [5.4266250e+04, 3.6841250e+04],
           [1.8522475e+04, 1.1722475e+04],
           [          nan, 3.2500000e+02],
           [2.6990475e+04, 1.2840475e+04],
           [8.7437700e+05, 4.6682700e+05]])
    
    编辑 我注意到你想要每年的结果作为“总计”的平均值, 不是每行(每年)的平均值

    要获得这样的结果,您可以仅依赖Numpy函数:

    # Separate the "wanted" columns
    a1 = df.iloc[:, 2:].values
    # Create a list of "sections" for each year
    a2 = np.array_split(a1, a1.shape[1] // 4, axis=1)
    # Compute mean for each "section"
    resNp = np.array([np.nanmean(a) for a in a2])
    
    对于我获得的样本数据(2004年和2005年的平均值):


    您只需要这4个季度或所有行的全年平均数?嗨,Andreas,我需要2019年之前每年4个季度的平均数。但您期望的输出显示的是每年平均数,而不是每个季度。嗨,Andreas,对不起,我误解了您的问题。我期望产出的平均值(例如2004年)是4个季度的平均数。例如,Q1:1000、Q2:2000、Q3:1000和Q4:2000,因此2004年的平均_的预期值为1500。希望这能增加一点清晰度。好的,你试过我答案中的代码了吗?应该可以按照您的意愿工作。@user14074078我不理解您的评论。嗨,安德烈亚斯,我能为您的代码寻求一些澄清吗?对于第1行,y.split”“[0],我猜您是在告诉程序,如果数据以后缀“_Q1”、“_Q2”、“_Q3”或“_Q4”结尾,则对所有列使用分隔符”“分割数据,但机器如何解释[0]上的部分。第二行似乎是每4次计数的计数器。第1行:获取所有列的列表,如果以四分之一结尾,则在“uu”处拆分,并取拆分字符串的第一部分(在索引0处)。只需执行第一行并打印(有效期为年)。第2行:在我们有一个有效年份的列表后,只返回列表中有4个条目的年份。现在,您已经在4x列中列出了所有年份。嗨,安德烈亚斯,感谢您在这方面的帮助!非常感谢!您好,Valdi,我在我的程序上尝试了您的代码,结果是DataError:没有要为result=df['Variables']]聚合的数值类型。join(df2.groupby(grpDct,axis=1.mean())我已更新了excel文件的链接,我试图在问题中处理该文件,以查看它是否有助于排除故障。问题的根源可能是表示NaN值的na字符串。请注意,read_excel默认情况下不会将它们识别为NaN,因此包含此类字符串的每一列可能都是对象类型(运行df.info()并检查输出以确认)。以NaN形式读取na字符串的步骤传递na_值='na'以读取excel。阅读有关读取excel的文档。它包括解释为NaN的值,例如大写NA,但小写NA不在此列表中。嗨,Valdi,感谢您在这方面的帮助!非常感谢!
    array([379909.89      , 200233.99090909])