Python 我怎样才能在熊猫身上形成这种聚集?

Python 我怎样才能在熊猫身上形成这种聚集?,python,pandas,dataframe,aggregate,data-wrangling,Python,Pandas,Dataframe,Aggregate,Data Wrangling,我有一个dataframe,它有分类列和数字列,我想根据分类列的值对数字列上的值(max、min、sum…)进行一些调整(因此我必须为每个分类列可以采用的每个值创建新列) 为了让它更容易理解,最好举个玩具的例子 假设我有这个数据帧: import pandas as pd df = pd.DataFrame({ 'ref' : [1, 1, 1, 2, 2, 3], 'value_type' : ['A', 'B', 'A', 'C', 'C', 'A'], '

我有一个dataframe,它有分类列和数字列,我想根据分类列的值对数字列上的值(max、min、sum…)进行一些调整(因此我必须为每个分类列可以采用的每个值创建新列)

为了让它更容易理解,最好举个玩具的例子

假设我有这个数据帧:

 import pandas as pd
 df = pd.DataFrame({
     'ref' : [1, 1, 1, 2, 2, 3],
     'value_type' : ['A', 'B', 'A', 'C', 'C', 'A'],
     'amount' : [100, 50, 20, 300, 150, 70]
}).set_index(['ref'])
我想根据value_类型的值对金额进行分组,并对每个引用进行分组。这种情况下的结果(假设只需要总和)如下:

df_result = pd.DataFrame({
    'ref' : [1, 2, 3],
    'sum_amount_A' : [120, 0, 70],
    'sum_amount_B' : [50, 0, 0],
    'sum_amount_C' : [0, 450, 0]
}).set_index('ref')
我试过一些有效的方法,但效率非常低。一次处理30000行需要几分钟

我所做的是:(我有一个数据帧,每个索引引用只有一行,称为df_final)

我相信应该有更好的方法来解决这个问题。。。提前谢谢

编辑:

当只有一列可以分组时,给出的答案是正确的。在实际数据帧中,我有几个列,我想在这些列上计算一些agg函数,但每个列上的值是分开的。我的意思是,我不希望列的每个值组合都有一个聚合值,而只希望列本身有一个聚合值

让我们举个例子

import pandas as pd
df = pd.DataFrame({
    'ref' : [1, 1, 1, 2, 2, 3],
    'sexo' : ['Hombre', 'Hombre', 'Hombre', 'Mujer', 'Mujer', 'Hombre'],
    'lugar_trabajo' : ['Campo', 'Ciudad', 'Campo', 'Ciudad', 'Ciudad', 'Campo'],
    'dificultad' : ['Alta', 'Media', 'Alta', 'Media', 'Baja', 'Alta'],
    'amount' : [100, 50, 20, 300, 150, 70]
}).set_index(['ref'])
此数据帧如下所示:

   sexo lugar_trabajo   dificultad  amount
ref             
1   Hombre  Campo       Alta         100
1   Hombre  Ciudad      Media        50
1   Hombre  Campo       Alta         20
2   Mujer   Ciudad      Media        300
2   Mujer   Ciudad      Baja         150
3   Hombre  Campo       Alta         70
如果我按多个列分组,或制作一个透视表(据我所知,这在某种程度上是等效的),则执行以下操作:

df.pivot_table(index='ref',columns=['sexo','lugar_trabajo','dificultad'],values='amount',aggfunc=[np.sum,np.min,np.max,len], dropna=False)
我将得到一个48列的数据帧(因为我有3*2*2个不同的值和4个agg函数)

实现我想要的结果的一种方法是:

df_agregado = pd.DataFrame(df.index).set_index('ref')

for col in ['sexo','lugar_trabajo','dificultad']:
    df_agregado = pd.concat([df_agregado, df.pivot_table(index='ref',columns=[col],values='amount',aggfunc=[np.sum,np.min,np.max,len])],axis=1)

我一个人做每一组,然后把它们全部做完。这样我得到28列(2*4+3*4+2*4)。它能工作,速度快,但不是很优雅。有没有其他方法可以得到这个结果呢?

更有效的方法是使用Pandas内置函数,而不是
进行循环。您应该采取两个主要步骤。
首先,您不仅需要按索引分组,还需要按索引和列分组:

res = df.groupby(['ref','value_type']).sum()
print(res)
此步骤的输出如下所示:

                amount
ref value_type        
1   A              120
    B               50
2   C              450
3   A               70
其次,您需要按如下方式取消堆叠多重索引:

df2 = res.unstack(level='value_type',fill_value=0)
输出将是您的期望输出:

    amount
value_type  A   B   C
ref         
1   120 50  0
2   0   0   450
3   70  0   0
作为可选步骤,您可以使用
droplevel
将其展平:

df2.columns = df2.columns.droplevel()

我对这个问题进行了编辑,因为在处理多个列时,按操作分组(在我的例子中)并不是我想要的。。。提前谢谢!对于编辑部分,我可以想到与您相同的想法。使用“ref”对每列进行分组,然后对结果进行concat。让我看看有没有更好的办法。
df2 = res.unstack(level='value_type',fill_value=0)
    amount
value_type  A   B   C
ref         
1   120 50  0
2   0   0   450
3   70  0   0
df2.columns = df2.columns.droplevel()
value_type  A   B   C
ref         
1   120 50  0
2   0   0   450
3   70  0   0