将行值转换为Pandas数据框中现有的预定义列

时间:2019-06-20 10:05:17

标签: python pandas

我有一个按金额排序的数据框,每个姓名的前5个类别如下:

| Name | Category | Amount |
|------|----------|--------|
| Abel | A        | 9.2    |
| Abel | B        | 3      |
| Abel | C        | 2.5    |
| Abel | E        | 2      |
| Abel | X        | 0      |
| Cain | W        | 93     |
| Cain | A        | 2      | 
|------|----------|--------|

这是我最终想要的:

| Name | Cat 1 | Cat 2 | Cat 3 | Cat 4 | Cat 5 |
|------|-------|-------|-------|-------|-------|
| Abel | A     | B     | C     | E     | X     |
| Cain | W     | A     | -     | -     |  -    |
|------|-------|-------|-------|-------|-------|

我尝试了df.pivot(“ Name”,“ Category”),但是它将值(例如A,B,...)设置为列名,但是我希望将5列预定义为“ Cat 1”改为“ Cat 5”,因此我不确定该如何做才能立即获得结果。另外,并非所有名称都有5行。例如该隐只有前2名,这意味着Cat 3,Cat 4和Cat5列应为null或“-”。有什么帮助吗?谢谢!

更新:

好,例如如果我所有的名字都只记录了2个类别,那么我还是想为前5个类别(即Cat 1,Cat 2,Cat 3,Cat 4,Cat 5)添加5个新列。

现在可以了

df["g"] = top5_jmi.groupby("Name").cumcount().add(1)

如果以后再旋转它,只会给我两列。如何获得5列?例如。

| Name | Category | Amount |
|------|----------|--------|
| Abel | A        | 9.2    |
| Abel | B        | 3      |
| Cain | W        | 93     |
| Cain | A        | 2      |
|------|----------|--------|

should still give me this:

| Name | Cat 1 | Cat 2 | Cat 3 | Cat 4 | Cat 5 |
|------|-------|-------|-------|-------|-------|
| Abel | A     |  B    |   -   |   -   |   -   |
| Cain | W     |  A    |   -   |   -   |   -   |
|------|-------|-------|-------|-------|-------|

1 个答案:

答案 0 :(得分:1)

使用:

#create counter column used for later columns names
df['g'] = df.groupby('Name').cumcount().add(1)
#filter top3
df = df[df['g'] <= 5]
#reshape by pivot
df2 = (df.pivot('Name','g','Category')
         .add_prefix('Type ')
         .reset_index()
         .rename_axis(None, axis=1)
         .fillna('-'))
print (df2)
   Name Type 1 Type 2 Type 3 Type 4 Type 5
0  Abel      A      B      C      E      X
1  Cain      W      A      -      -      -

编辑:使用DataFrame.reindex添加缺少的列:

df['g'] = df.groupby('Name').cumcount().add(1)
#filter top3
df = df[df['g'] <= 5]
#reshape by pivot
df2 = (df.pivot('Name','g','Category')
         .reindex(range(1, 6), axis=1)
         .add_prefix('Type ')
         .reset_index()
         .rename_axis(None, axis=1)
         .fillna('-'))
print (df2)
   Name Type 1 Type 2 Type 3 Type 4 Type 5
0  Abel      A      B      -      -      -
1  Cain      W      A      -      -      -