这是一个有效的方法来聚合带有多个自定义函数的多列,并使用Pandas数据框中的多个功能吗?

2024-04-26 06:09:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧。我要聚合多个列。对于每一列,都有多个聚合函数。这很简单。棘手的部分是,在每个聚合函数中,我希望访问另一列中的数据。你知道吗

我该如何有效地做这件事?以下是我已经掌握的代码:

import pandas

data = [
    {
        'id': 1,
        'A': 1,
        'B': 1,
        'C': 1,
        'D': 1,
        'E': 1,
        'F': 1,
    },
    {
        'id': 1,
        'A': 2,
        'B': 2,
        'C': 2,
        'D': 2,
        'E': 2,
        'F': 2,
    },
    {
        'id': 2,
        'A': 3,
        'B': 3,
        'C': 3,
        'D': 3,
        'E': 3,
        'F': 3,
    },
    {
        'id': 2,
        'A': 4,
        'B': 4,
        'C': 4,
        'D': 4,
        'E': 4,
        'F': 4,
    },
]

df = pandas.DataFrame.from_records(data)


def get_column(column, column_name):
    return df.iloc[column.index][column_name]


def agg_sum_a_b(column_a):
    return column_a.sum() + get_column(column_a, 'B').sum()


def agg_sum_a_b_divide_c(column_a):
    return (column_a.sum() + get_column(column_a, 'B').sum()) / get_column(column_a, 'C').sum()


def agg_sum_d_divide_sum_e_f(column_d):
    return column_d.sum() / (get_column(column_d, 'E').sum() + get_column(column_d, 'F').sum())


def multiply_then_sum(column_e):
    return (column_e * get_column(column_e, 'F')).sum()


df_grouped = df.groupby('id')
df_agg = df_grouped.agg({
    'A': [agg_sum_a_b, agg_sum_a_b_divide_c, 'sum'],
    'D': [agg_sum_d_divide_sum_e_f, 'sum'],
    'E': [multiply_then_sum]
})

此代码生成以下数据帧:

             A                                                 D                     E    
   agg_sum_a_b agg_sum_a_b_divide_c sum agg_sum_d_divide_sum_e_f sum multiply_then_sum
id                                                                  
1            6                    2   3                      0.5   3                 5
2           14                    2   7                      0.5   7                25

我做得对吗?有没有更好的办法?我发现在聚合函数中访问另一列中的数据的方式有点尴尬。你知道吗

我使用的实际数据和代码有大约20列和大约40个聚合函数。可能还有数百个组,每个组都有数百行。你知道吗

当我使用真实数据和聚合函数进行此操作时,可能需要几分钟的时间,这对于我来说太慢了。有什么办法能提高效率吗?你知道吗

编辑:我正在使用Python3.6和pandas 0.23.0。谢谢!
edit2:添加了一个示例,其中我不调用列上的sum()。你知道吗


Tags: 数据函数代码idpandasdfgetreturn
1条回答
网友
1楼 · 发布于 2024-04-26 06:09:21

首先,我认为您需要更多的apply而不是agg来同时访问不同的列。这里有一个想法如何改变一点你想做的。让我们首先创建一个函数,重新组合要执行的操作,并将它们作为结果列表返回:

def operations_to_perfom (df_g):

    df_g_sum = df_g.sum() #can do the same with mean, min, max ...

    # return all the operation you want 
    return  [ df_g_sum['A'] + df_g_sum['B'], 
              (df_g_sum['A'] + df_g_sum['B'])/df_g_sum['C'], 
              df_g_sum['A'], 
              float(df_g_sum['D'])/(df_g_sum['E']+df_g_sum['F']),
              (df_g['E']*df_g['F']).sum() ]

#use apply to create a serie with id as index and a list of agg
df_values = df.groupby('id').apply(operations_to_perfom)

# now create the result dataframe from df_values with tolist() and index
df_agg = pd.DataFrame( df_values.tolist(), index=df_values.index, 
         columns=pd.MultiIndex.from_arrays([['A']*3+['D']+['E'], 
                 ['agg_sum_a_b', 'agg_sum_a_b_div_c' ,'sum', 'agg_sum_d_div_sum_e_f', 'e_mult_f']]))

df_agg看起来像:

             A                                           D        E
   agg_sum_a_b agg_sum_a_b_div_c sum agg_sum_d_div_sum_e_f e_mult_f
id                                                                 
1            6                 2   3                   0.5        5
2           14                 2   7                   0.5       25

相关问题 更多 >

    热门问题