使用 pivot table pandas 后如何摆脱多级索引?

How to get rid of multilevel index after using pivot table pandas?

我有以下数据框(真实数据框比这个大得多):

sale_user_id    sale_product_id count
1                 1              1
1                 8              1
1                 52             1
1                 312            5
1                 315            1

然后使用以下代码重塑它以将 sale_product_id 中的值移动为列 headers:

reshaped_df=id_product_count.pivot(index='sale_user_id',columns='sale_product_id',values='count')

结果数据框是:

sale_product_id -1057   1   2   3   4   5   6   8   9   10  ... 98  980 981 982 983 984 985 986 987 99
sale_user_id                                                                                    
1                NaN    1.0 NaN NaN NaN NaN NaN 1.0 NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3                NaN    1.0 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4                NaN    NaN 1.0 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

如您所见,我们有一个多级索引,我需要的是在没有多级索引的第一列中有 sale_user_is:

我采用以下方法:

reshaped_df.reset_index()

结果会像这样我还有 sale_product_id 列,但我不再需要它了:

sale_product_id sale_user_id    -1057   1   2   3   4   5   6   8   9   ... 98  980 981 982 983 984 985 986 987 99
0                          1    NaN 1.0 NaN NaN NaN NaN NaN 1.0 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1                          3    NaN 1.0 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2                          4    NaN NaN 1.0 NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 

我可以对这个数据框进行子集化以摆脱 sale_product_id 但我认为不会 efficient.I 我正在寻找一种有效的方法来摆脱多级索引,同时重塑原始数据数据框

您只需删除 index name,使用 rename_axispandas 0.18.0 中的新功能):

print (reshaped_df)
sale_product_id  1    8    52   312  315
sale_user_id                            
1                  1    1    1    5    1

print (reshaped_df.index.name)
sale_user_id

print (reshaped_df.rename_axis(None))
sale_product_id  1    8    52   312  315
1                  1    1    1    5    1

另一个解决方案在 pandas 下面 0.18.0:

reshaped_df.index.name = None
print (reshaped_df)

sale_product_id  1    8    52   312  315
1                  1    1    1    5    1

如果需要删除 columns name 还有:

print (reshaped_df.columns.name)
sale_product_id

print (reshaped_df.rename_axis(None).rename_axis(None, axis=1))
   1    8    52   312  315
1    1    1    1    5    1

另一个解决方案:

reshaped_df.columns.name = None
reshaped_df.index.name = None
print (reshaped_df)
   1    8    52   312  315
1    1    1    1    5    1

通过评论编辑:

你需要 reset_index 参数 drop=True:

reshaped_df = reshaped_df.reset_index(drop=True)
print (reshaped_df)
sale_product_id  1    8    52   312  315
0                  1    1    1    5    1

#if need reset index nad remove column name
reshaped_df = reshaped_df.reset_index(drop=True).rename_axis(None, axis=1)
print (reshaped_df)
   1    8    52   312  315
0    1    1    1    5    1

如果只需要去掉列名的:

reshaped_df = reshaped_df.rename_axis(None, axis=1)
print (reshaped_df)
              1    8    52   312  315
sale_user_id                         
1               1    1    1    5    1

编辑 1:

因此,如果需要从 index 创建新列并删除 columns names:

reshaped_df =  reshaped_df.rename_axis(None, axis=1).reset_index() 
print (reshaped_df)
   sale_user_id  1  8  52  312  315
0             1  1  1   1    5    1

它对我有用的方式是

df_cross=pd.DataFrame(pd.crosstab(df[c1], df[c2]).to_dict()).reset_index()

制作数据框

import random

d = {'Country': ['Afghanistan','Albania','Algeria','Andorra','Angola']*2, 
     'Year': [2005]*5 + [2006]*5, 'Value': random.sample(range(1,20),10)}
df = pd.DataFrame(data=d)

df:

                Country         Year   Value    
1               Afghanistan     2005    6
2               Albania         2005    13
3               Algeria         2005    10
4               Andorra         2005    11
5               Angola          2005    5
6               Afghanistan     2006    3
7               Albania         2006    2
8               Algeria         2006    7
9               Andorra         2006    3
10              Angola          2006    6

枢轴

table = df.pivot(index='Country',columns='Year',values='Value')

Table:

Year    Country         2005    2006
0       Afghanistan     16      9
1       Albania         17      19
2       Algeria         11      7
3       Andorra         5       12
4       Angola          6       18

我希望 'Year' 成为 'index':

clean_tbl = table.rename_axis(None, axis=1).reset_index(drop=True)

clean_tbl:

    Country         2005    2006
0   Afghanistan     16      9
1   Albania         17      19
2   Algeria         11      7
3   Andorra         5       12
4   Angola          6       18

完成!

我们需要 reset_index() 将索引列重置回数据框中,然后 rename_axis() 将索引重命名为 None 并将列重命名为它们的 axis=1 (列 headers) 值。

reshaped_df = reshaped_df.reset_index().rename_axis(None, axis=1)

使用 pivot 从长格式转换为宽格式:

import pandas
df = pandas.DataFrame({
    "lev1": [1, 1, 1, 2, 2, 2],
    "lev2": [1, 1, 2, 1, 1, 2],
    "lev3": [1, 2, 1, 2, 1, 2],
    "lev4": [1, 2, 3, 4, 5, 6],
    "values": [0, 1, 2, 3, 4, 5]})
df_wide = df.pivot(index="lev1", columns=["lev2", "lev3"], values="values")
df_wide

# lev2    1         2
# lev3    1    2    1    2
# lev1
# 1     0.0  1.0  2.0  NaN
# 2     4.0  3.0  NaN  5.0

重命名(有时令人困惑的)轴名称

df_wide.rename_axis(columns=[None, None])

#         1         2
#         1    2    1    2
# lev1
# 1     0.0  1.0  2.0  NaN
# 2     4.0  3.0  NaN  5.0

您还可以使用 MultiIndex 对象的 to_flat_index 方法将其转换为元组列表,然后您可以将其与列表理解连接并使用它来覆盖 .columns 数据框的属性。

# create a dataframe
df = pd.DataFrame({"a": [1, 2, 3, 1], "b": ["x", "x", "y", "y"], "c": [0.1, 0.2, 0.1, 0.2]})


    a   b   c
0   1   x   0.1
1   2   x   0.2
2   3   y   0.1
3   1   y   0.2
# pivot the dataframe
df_pivoted = df.pivot(index="a", columns="b")

    c
b   x   y
a       
1   0.1 0.2
2   0.2 NaN
3   NaN 0.1

现在让我们覆盖 .columns 属性和 .reset_index():

df_pivoted.columns = ["_".join(tup) for tup in df_pivoted.columns.to_flat_index()]
df_pivoted.reset_index()

    a   c_x c_y
0   1   0.1 0.2
1   2   0.2 NaN
2   3   NaN 0.1