使用dataframe的列值作为索引和列名称

时间:2017-11-16 13:54:39

标签: pandas

我正在使用如下所示的数据框:

    Client_ID   Product_ID   Cost
0      4            1         40
1      4            2         32
2      5            1         38
3      6            7         89
4      7            3         21
5      4            5         45
6      2            5         23
7      2            4         71
8      5            8         11
9      7            8         14

对于每对'Client_ID, Product_ID',数据帧中只有一个出现/行。

我想构建一个数据框,其中Product_ID是索引,列名称是客户端名称,而成本变为每个单元格中的值,它看起来像这样:

                     Client_ID
Product_ID    1   2   3   4   5   6   7
   1          x   x   x  40  38   x   x
   2          x   x   x  32   x   x   x
   3          x   x   x   x   x   x  21
   4          x  71   x   x   x   x   x
   5          x  23   x  45   x   x   x
   6          x   x   x   x   x   x   x
   7          x   x   x   x   x  89   x
   8          x   x   x   x  11   x  14
   9          x   x   x   x   x   x   x
  10          x   x   x   x   x   x   x

我试图通过这样做来实现这一目标:

df.pivot(index='Product_ID', columns='Client_ID')

但它没有用,我尝试先将Product_ID指数放在首位,然后再进行调整:

df = df.set_index('Product_ID')
df.index.name = None
df.pivot(columns='Client_ID')

也没有成功。

有人知道如何实现这样的目标吗?

感谢您的帮助。

修改

Product_ID值是字符串。

1 个答案:

答案 0 :(得分:1)

似乎需要pivot + reindex来添加缺少的行/列:

#reindex by union of columns
a = np.union1d(df['Client_ID'],df['Product_ID'])
df = df.pivot(index='Product_ID', columns='Client_ID', values='Cost')
       .reindex(index=a, columns=a)
print (df)
Client_ID    1     2   3     4     5     6     7   8
Product_ID                                          
1          NaN   NaN NaN  40.0  38.0   NaN   NaN NaN
2          NaN   NaN NaN  32.0   NaN   NaN   NaN NaN
3          NaN   NaN NaN   NaN   NaN   NaN  21.0 NaN
4          NaN  71.0 NaN   NaN   NaN   NaN   NaN NaN
5          NaN  23.0 NaN  45.0   NaN   NaN   NaN NaN
6          NaN   NaN NaN   NaN   NaN   NaN   NaN NaN
7          NaN   NaN NaN   NaN   NaN  89.0   NaN NaN
8          NaN   NaN NaN   NaN  11.0   NaN  14.0 NaN

或者:

#1 to max value of columns
b = range(1,df['Client_ID'].max()+1)
a = range(1,df['Product_ID'].max()+1)
df = df.pivot(index='Product_ID', columns='Client_ID', values='Cost')
       .reindex(index=a, columns=b)
print (df)
Client_ID    1     2   3     4     5     6     7
Product_ID                                      
1          NaN   NaN NaN  40.0  38.0   NaN   NaN
2          NaN   NaN NaN  32.0   NaN   NaN   NaN
3          NaN   NaN NaN   NaN   NaN   NaN  21.0
4          NaN  71.0 NaN   NaN   NaN   NaN   NaN
5          NaN  23.0 NaN  45.0   NaN   NaN   NaN
6          NaN   NaN NaN   NaN   NaN   NaN   NaN
7          NaN   NaN NaN   NaN   NaN  89.0   NaN
8          NaN   NaN NaN   NaN  11.0   NaN  14.0

详情:

print (df.pivot(index='Product_ID', columns='Client_ID', values='Cost'))
Client_ID      2     4     5     6     7
Product_ID                              
1            NaN  40.0  38.0   NaN   NaN
2            NaN  32.0   NaN   NaN   NaN
3            NaN   NaN   NaN   NaN  21.0
4           71.0   NaN   NaN   NaN   NaN
5           23.0  45.0   NaN   NaN   NaN
7            NaN   NaN   NaN  89.0   NaN
8            NaN   NaN  11.0   NaN  14.0

如有必要,最后更换NaN,但获取混合值 - 带字符串的数字:

df = df.fillna('x')