【问题标题】:Unstack row label (pivot table)取消堆叠行标签(数据透视表)
【发布时间】:2019-08-10 00:21:44
【问题描述】:

我想使用 Python 取消堆叠行标签名称,并已清理数据以删除“总计”和“na”行。

代码:

Description   | Table    |  Chair
***Manila***  |          |   
Apple         |     1    |    3
Pair          |     0    |    1
Orange        |     1    |    0
Watermelon    |     0    |    5
Banana        |     0    |    7
***Quezon***  |          |  
DragonFruit   |     0    |    0
StarApple     |     0    |    0
Longan        |     0    |    1
Cherries      |     1    |    2
Mango         |     0    |    5

表格图片:

我希望代码看起来如何:

Description  |   Day   |    Table  |  Chair
Manila    |    1     |     1    |   3
Manila    |    2     |     0    |   1
Manila    |    3     |     1    |   0
Manila    |    4     |     0    |   5
Manila    |    5     |     0    |   7
Quezon    |    1     |     0    |   0
Quezon    |    2     |     0    |   0
Quezon    |    3     |     0    |   1
Quezon    |    4     |     1    |   2
Quezon    |    5     |     0    |   5

表格图片:

【问题讨论】:

  • 欢迎玛莎F!从您提供的示例数据中我无法确定,但请尝试df = df.reset_index()。说明:当一个pandas索引有连续重复标签时,pandas隐藏所有重复标签,只显示第一个。每行的标签仍然存在,强制它们显示的一种方法是重置索引,默认情况下将其作为最左边的列插入。当然,这会修改 DataFrame,如果您不需要使用索引操作,这可能会很好。
  • @PeterLeimbigler 我已经尝试运行代码 df.reset_index() 除了列索引(来自另一个文档)之外返回相同的值。不确定代码是如何工作的。行标签/标题的输出仍然是马尼拉 NaN NaN NaN。在插入基于 Day 为 NaN 的新列时尝试了 for 循环,结果是一个 12 * 12 表。
  • 了解您如何创建数据框可能会有所帮助。
  • @busybear 数据框是使用 df = pd.read_excel(file_path, nrows=100, skiprows= 10, header=1) 创建的。标头 [0,1] 不起作用,因为原始文件有多个 NaN。

标签: python python-3.x pandas numpy python-3.7


【解决方案1】:

IIUC,试试这个:

df = pd.DataFrame({'Description':['Manila',1,2,3,4,5,'Quezon',1,2,3,4,5],
                  'Table':['',1,0,1,0,0,'',0,0,0,1,0],
                  'Chair':['',3,1,0,5,7,'',0,0,1,2,5]})

print(df)

输出:

   Description Table Chair
0       Manila            
1            1     1     3
2            2     0     1
3            3     1     0
4            4     0     5
5            5     0     7
6       Quezon            
7            1     0     0
8            2     0     0
9            3     0     1
10           4     1     2
11           5     0     5

仅使用正则表达式从单词创建一个新列并向前填充:

df['Group'] = df['Description'].str.extract('(\w+)').ffill()

#Drop those "header records"  
df_out = df[df['Description'].str.contains('\w+').isna()]\
           .reindex(['Group','Description','Table','Chair'], axis=1)

print(df_out)

输出:

     Group Description Table Chair
1   Manila           1     1     3
2   Manila           2     0     1
3   Manila           3     1     0
4   Manila           4     0     5
5   Manila           5     0     7
7   Quezon           1     0     0
8   Quezon           2     0     0
9   Quezon           3     0     1
10  Quezon           4     1     2
11  Quezon           5     0     5

#Another way, look for blanks in table or chairs:

 df = pd.DataFrame({'Description':['Manila',1,2,3,4,5,'Quezon',1,2,3,4,5],
                  'Table':[np.nan,1,0,1,0,0,np.nan,0,0,0,1,0],
                  'Chair':[np.nan,3,1,0,5,7,np.nan,0,0,1,2,5]})


m = df['Table'].isna()

df['Group'] = df.loc[m, 'Description']

df['Group'] = df['Group'].ffill()

df_out = df.loc[~m].reindex(['Group','Description','Table','Chair'], axis=1)

输出:

    Group Description  Table  Chair
1   Manila           1    1.0    3.0
2   Manila           2    0.0    1.0
3   Manila           3    1.0    0.0
4   Manila           4    0.0    5.0
5   Manila           5    0.0    7.0
7   Quezon           1    0.0    0.0
8   Quezon           2    0.0    0.0
9   Quezon           3    0.0    1.0
10  Quezon           4    1.0    2.0
11  Quezon           5    0.0    5.0

【讨论】:

    【解决方案2】:

    如果您的表是 pandas 数据框,只需重置索引,如下图所示。

    【讨论】:

    • 嗨 Gustavo,我的 print(df) 在描述下返回马尼拉和奎松。新的列索引是如何从 print(df) 打印出来的?谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    • 2019-02-14
    • 2016-09-11
    • 1970-01-01
    相关资源
    最近更新 更多