如何根据类别将pandas数据帧行转换为列?

时间:2016-09-22 10:00:37

标签: python pandas

我有一个带有类别变量和一些数字变量的pandas数据框。像这样:

ls = [{'count':5, 'module':'payroll', 'id':2}, {'count': 53, 'module': 'general','id':2}, {'id': 5,'count': 35, 'module': 'tax'}, ]
df = pd.DataFrame.from_dict(ls)

df看起来像这样:

 df
Out[15]: 
   count  id   module
0      5   2  payroll
1     53   2  general
2     35   5      tax

我想将转换(转置是正确的词?)模块变量分为列和按ID分组。如下所示:

   general_count  id  payroll_count  tax_count
0           53.0   2            5.0        NaN
1            NaN   5            NaN       35.0

一种方法是使用apply:

df['payroll_count'] = df.id.apply(lambda x: df[df.id==x][df.module=='payroll'])

然而,这有许多缺点:

  1. 费用高,耗时太长

  2. 创建工件并清空     需要清理的数据框。

  3. 我觉得有更好的方法可以通过pandas groupby实现这一目标,但无法更有效地找到同一操作的方法。请帮忙。

2 个答案:

答案 0 :(得分:7)

您可以按照先创建新index和最后column的列使用groupby。然后需要以某种方式进行聚合 - 我使用mean,然后通过DataFrame.squeeze将一列DataFrame转换为Series(然后不必删除列中的顶级Multiindex)并重新整形由unstack。最后add_suffix到列名称:

df = df.groupby(['id','module']).mean().squeeze().unstack().add_suffix('_count')
print (df)
module  general_count  payroll_count  tax_count
id                                             
2                53.0            5.0        NaN
5                 NaN            NaN       35.0

使用pivot的另一个解决方案,然后需要通过Multiindex从列中删除list comprehension

df = df.pivot(index='id', columns='module')
df.columns = ['_'.join((col[1], col[0])) for col in df.columns]
print (df)
    general_count  payroll_count  tax_count
id                                         
2            53.0            5.0        NaN
5             NaN            NaN       35.0

答案 1 :(得分:0)

您可以使用set_indexunstack

In [2]: df.set_index(['id','module'])['count'].unstack().add_suffix('_count').reset_index()
Out[2]:
module  id  general_count  payroll_count  tax_count
0        2           53.0            5.0        NaN
1        5            NaN            NaN       35.0