df=pd.DataFrame(np.random.randn(20).reshape(4,5),index=[['a','a','b','b'],[1,2,3,4]],columns=[10,20,30,40,50])
In [96]: df
Out[96]:
10 20 30 40 50
a 1 0.945775 0.768337 0.851630 -1.050475 -1.102554
2 -0.366129 0.353388 -0.722637 -0.056877 1.178270
b 3 0.885536 0.210911 2.067309 1.283721 -0.432906
4 0.173504 1.263630 1.264698 0.913879 1.156815
In [98]: df.stack()
Out[98]:
a 1 10 0.945775
20 0.768337
30 0.851630
40 -1.050475
50 -1.102554
2 10 -0.366129
20 0.353388
30 -0.722637
40 -0.056877
50 1.178270
b 3 10 0.885536
20 0.210911
30 2.067309
40 1.283721
50 -0.432906
4 10 0.173504
20 1.263630
30 1.264698
40 0.913879
50 1.156815
In [99]: df.stack().unstack()
Out[99]:
10 20 30 40 50
a 1 0.945775 0.768337 0.851630 -1.050475 -1.102554
2 -0.366129 0.353388 -0.722637 -0.056877 1.178270
b 3 0.885536 0.210911 2.067309 1.283721 -0.432906
4 0.173504 1.263630 1.264698 0.913879 1.156815
以上利用了Pandas的层次化索引,实际上这也是层次化索引一个主要的用途,结合本例我们可以把代码改成如下:
result_df=pd.read_sql('select UserName,Subject,Score from TEST',conn)
# 在从数据库中获取的数据格式是这样的:
UserName Subject Score
0 张三 语文 80.0
1 张三 数学 90.0
2 张三 英语 70.0
3 张三 生物 85.0
4 李四 语文 80.0
5 李四 数学 92.0
6 李四 英语 76.0
7 王五 语文 60.0
8 王五 数学 82.0
9 王五 英语 96.0
10 王五 生物 78.0
# 如果要使用层次化索引,那么我们只需要把UserName和Subject列设置为层次化索引,Score为其对应的值即可,我们借用set_index()函数:
df=result_df.set_index(['UserName','Subject'])
In [112]: df.unstack()
Out[112]:
Score
Subject 数学 生物 英语 语文
UserName
张三 90.0 85.0 70.0 80.0
李四 92.0 NaN 76.0 80.0
王五 82.0 78.0 96.0 60.0
# 使用stack可以将unstack的结果转回来,这样就也在形式上实现了行列互转,之后的操作基本一致了。