首页 > 解决方案 > 熊猫:groupby unstack,重复索引错误

问题描述

我无法旋转/重塑我的数据框。手术后melt(),我有以下df:

|----|------|------|------------|
| ID | Rank | Var  | Val        |
|----|------|------|------------|
|  1 |   1  | date | 2020-01-01 |
|----|------|------|------------|
|  1 |   2  | date | 2020-02-01 |
|----|------|------|------------|
|  2 |   1  | date | 2020-01-01 |
|----|------|------|------------|
|  2 |   2  | date | 2020-02-01 |
|----|------|------|------------|
|  1 |   1  | amt  | 320        |
|----|------|------|------------|
|  1 |   2  | amt  | 480        |
|----|------|------|------------|
|  2 |   1  | amt  | 620        |
|----|------|------|------------|
|  2 |   2  | amt  | 400        |
|----|------|------|------------|

我正在寻找的结果是将排名值转换为列:

|----|------|------------|------------|
| ID | Var  | 1          | 2          |
|----|------|------------|------------|
| 1  | date | 2020-01-01 | 2020-02-01 |
|    |------|------------|------------|
|    | amt  | 320        | 480        |
|----|------|------------|------------|
| 2  | date | 2020-01-01 | 2020-02-01 |
|    |------|------------|------------|
|    | amt  | 620        | 400        |
|----|------|------------|------------|

立即尝试unstack(level='Rank')导致

ValueError:索引包含重复的条目,无法重塑

好的,我们确实有重复IDs,让我们groupby合并:

df.set_index(['ID', 'Rank']).groupby(['ID', 'Rank']).apply(lambda x: x)

apply()只是为了我们可以返回一个数据框并预览结果,它们是:

|----|------|------|------------|
| ID | Rank | Var  | Val        |
|----|------|------|------------|
|  1 |   1  | date | 2020-01-01 |
|    |------|------|------------|
|    |   1  | amt  | 320        |
|    |------|------|------------|
|    |   2  | date | 2020-02-01 |
|    |------|------|------------|
|    |   2  | amt  | 480        |
|----|------|------|------------|
|  2 |   1  | date | 2020-01-01 |
|    |------|------|------------|
|    |   2  | date | 2020-02-01 |
|    |------|------|------------|
|    |   1  | amt  | 620        |
|    |------|------|------------|
|    |   2  | amt  | 400        |
|----|------|------|------------|

这更近了。现在我们只需要将 Rank 转换为 cols:

df.set_index(['ID', 'Rank']).groupby(['ID', 'Rank']).apply(lambda x: x).unstack(level='Rank')

ValueError:索引包含重复的条目,无法重塑

???

我也尝试使用pivot_table,但并非所有列都是数字的(上面的示例已简化,但您可以在此处看到日期,这会抛出 pivot_table)。

我似乎只有一种方法,但我尝试过拆垛,重新索引,旋转,explode()-ing,我只是无法弄清楚最后一部分......

如何获得所需的数据框?

谢谢!

标签: pythonpandasdataframe

解决方案


您的问题是索引键必须是唯一的才能取消堆叠。

首先,让我们重新创建这个玩具示例

import pandas as pd
from IPython.display import display

df= pd.DataFrame(columns=['ID', 'Rank','Var', 'Val'],  data=[
    [1,1,'date', '2020-01-01'],
    [1,2,'date','2020-02-01'],
    [2,1,'date','2020-02-01'],
    [2,2,'date','2020-02-01'],
    [1,1,'amt',320],
    [1,2,'amt',480],
    [2,1,'amt',620],
    [2,2,'amt',400],
])

df = df.set_index(['ID', 'Rank'])
display(df)

现在,让我们解决

让我们将唯一键放入索引中,即IDandVar字段。现在拆垛是微不足道的

df.set_index('Var', append=True).unstack('Rank')

推荐阅读