pivot_table vs groupby:列名

时间:2018-05-12 16:22:23

标签: python pandas group-by pivot-table

df_tier

device_id   month_id    net_grp     watch_hours class
843         201707      TCH         0.250277    Ser
896         201803      NJV         0.820833    Ser
748         201711      SHX         2.461111    Sr
115         201712      SPE         1.478055    Opter
107         201802      US          2.575555    Opter
249         201710      ECC         3.869166    Ser
786         201711      NCK         0.563888    Opter
183         201802      HO          1.690555    Opter
752         201712      LC          0.993611    Opter

我正在对数据集执行数据透视操作,最终结果将包含大约500万行和600列。 以上是创建数据透视的数据样本。

#Pivot
df_tier.pivot_table(index=['device_id'],
                        columns = 'net_grp',
                        values = 'watch_hours',
                        aggfunc = sum,fill_value = 0).reset_index()

对200000条记录的样本执行此操作大约需要93.7毫秒,当我按以下方式分组时:

#Grouby
df_tier.groupby(['device_id','net_grp']).agg({'tuning_hours':['sum']}).unstack(level='net_grp').fillna(0).reset_index().set_index('device_id')

需要大约15毫秒。

然而,pivot的输出更有用,因为它包含正确的列名,而来自groupby的那个:

分组中的列名称不正确,

(' watch_hours''和'' TCH&#39),(' watch_hours''和' ' SPE&#39),(' watch_hours''和'' NCK&#39)

如何从这些列名中仅获取net_grp说TCH?

我想在这里使用groupby,因为在运行整个数据时存在性能问题。有人可以帮我正确地获取列名吗?

由于

1 个答案:

答案 0 :(得分:2)

我建议使用sum而不是agg来删除列中Multiindex的第一个和第二个不必要的级别:

df1 = (df_tier.groupby(['device_id','net_grp'])['watch_hours']
              .sum()
              .unstack(level='net_grp', fill_value=0))
print (df1)
net_grp         ECC        HO        LC       NCK       NJV       SHX  \
device_id                                                               
107        0.000000  0.000000  0.000000  0.000000  0.000000  0.000000   
115        0.000000  0.000000  0.000000  0.000000  0.000000  0.000000   
183        0.000000  1.690555  0.000000  0.000000  0.000000  0.000000   
249        3.869166  0.000000  0.000000  0.000000  0.000000  0.000000   
748        0.000000  0.000000  0.000000  0.000000  0.000000  2.461111   
752        0.000000  0.000000  0.993611  0.000000  0.000000  0.000000   
786        0.000000  0.000000  0.000000  0.563888  0.000000  0.000000   
843        0.000000  0.000000  0.000000  0.000000  0.000000  0.000000   
896        0.000000  0.000000  0.000000  0.000000  0.820833  0.000000   

net_grp         SPE       TCH        US  
device_id                                
107        0.000000  0.000000  2.575555  
115        1.478055  0.000000  0.000000  
183        0.000000  0.000000  0.000000  
249        0.000000  0.000000  0.000000  
748        0.000000  0.000000  0.000000  
752        0.000000  0.000000  0.000000  
786        0.000000  0.000000  0.000000  
843        0.000000  0.250277  0.000000  
896        0.000000  0.000000  0.000000 

如果想要使用agg的解决方案,可以按droplevel删除第一级和第二级:

df1 = (df_tier.groupby(['device_id','net_grp'])
              .agg({'watch_hours':['sum']})
              .unstack(level='net_grp', fill_value=0))

df1.columns = df1.columns.droplevel([0,1])