我有一个带有类别变量和一些数字变量的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'])
然而,这有许多缺点:
费用高,耗时太长
创建工件并清空 需要清理的数据框。
我觉得有更好的方法可以通过pandas groupby实现这一目标,但无法更有效地找到同一操作的方法。请帮忙。
答案 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_index
和unstack
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