将多索引/多级数据帧减少为单个索引,单个级别

dar*_*nge 3 python dataframe pandas

假设我有一个如下所示的数据框:

>>> df
   Year   MPG VehicleType FuelType
0  2000  20.5         Car      Gas
1  2009  22.3         Car      Gas
2  2017  50.9         Car      Gas
3  2000  14.7         Car   Diesel
4  2009  18.0         Car   Diesel
5  2017  22.2         Car   Diesel
Run Code Online (Sandbox Code Playgroud)

我需要VehicleType根据列的值将FuelType列拆分为两列,使用Year列作为索引.我曾经pivot_table正确地拆分列.

>>> pd.pivot_table(df, columns=['VehicleType', 'FuelType'], values='MPG', index=['Year'])
VehicleType    Car      
FuelType    Diesel   Gas
Year                    
2000          14.7  20.5
2009          18.0  22.3
2017          22.2  50.9
Run Code Online (Sandbox Code Playgroud)

这很棒,但它会产生一个多索引的数据帧,出于我的目的,我不想要它.

我试图得到一个结果,看起来事情是这样的:

Year Car_Diesel_MPG Car_Gas_MPG
2000           14.7        20.5
2009           18.0        22.3
2017           22.2        50.9
Run Code Online (Sandbox Code Playgroud)

我努力实现这一目标导致了一些非常讨厌的代码.有一个简单的方法吗?

sac*_*cuL 5

您可以使用连接多索引的级别+,并将其用作数据透视表的列:

# Same as your original privot table:
df2 = pd.pivot_table(df, columns=['VehicleType', 'FuelType'], values='MPG', index=['Year'])

df2.columns = df2.columns.get_level_values(0)+'_'+df2.columns.get_level_values(1)+'_MPG'

>>> df2
      Car_Diesel_MPG  Car_Gas_MPG
Year                             
2000            14.7         20.5
2009            18.0         22.3
2017            22.2         50.9
Run Code Online (Sandbox Code Playgroud)


piR*_*red 5

使用set_axis,mapjoin

df2.set_axis(df2.columns.map('_'.join), axis=1, inplace=False).add_suffix('_MPG')

      Car_Diesel_MPG  Car_Gas_MPG
Year                             
2000            14.7         20.5
2009            18.0         22.3
2017            22.2         50.9
Run Code Online (Sandbox Code Playgroud)

groupby 用一个 dict

m = {t: '_'.join(t) for t in df2.columns}
df2.groupby(m, axis=1).mean().add_suffix('_MPG')

      Car_Diesel_MPG  Car_Gas_MPG
Year                             
2000            14.7         20.5
2009            18.0         22.3
2017            22.2         50.9
Run Code Online (Sandbox Code Playgroud)

这些都可以 reset_index

m = {t: '_'.join(t) for t in df2.columns}
df2.groupby(m, axis=1).mean().add_suffix('_MPG').reset_index()

   Year  Car_Diesel_MPG  Car_Gas_MPG
0  2000            14.7         20.5
1  2009            18.0         22.3
2  2017            22.2         50.9
Run Code Online (Sandbox Code Playgroud)

groupby 代替 pivot_table

df.groupby(
    ['Year', df.VehicleType.str.cat(df.FuelType, sep='_').add('_MPG').values]
).MPG.sum().unstack().reset_index()

   Year  Car_Diesel_MPG  Car_Gas_MPG
0  2000            14.7         20.5
1  2009            18.0         22.3
2  2017            22.2         50.9
Run Code Online (Sandbox Code Playgroud)