Python 我怎样才能在熊猫身上形成这种聚集?
我有一个dataframe,它有分类列和数字列,我想根据分类列的值对数字列上的值(max、min、sum…)进行一些调整(因此我必须为每个分类列可以采用的每个值创建新列) 为了让它更容易理解,最好举个玩具的例子 假设我有这个数据帧: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'], '
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