如何将pandas透视表转换为数据框
我想用数据透视表来总结一个数据集,然后能够像使用数据框一样访问透视表中的信息。
想象一下,有一个分层的数据集,里面有在医院接受治疗的病人,还有这些医院所在的地区:
import pandas as pd
example_data = {'patient' : ['p1','p2','p3','p4','p5','p6','p7','p8','p9','p10','p11','p12','p13','p14','p15','p16','p17','p18','p19','p20','p21','p22','p23','p24','p25','p26','p27','p28','p29','p30','p31','p32','p33','p34','p35','p36','p37','p38','p39','p40','p41','p42','p43','p44','p45','p46','p47','p48','p49','p50','p51','p52','p53','p54','p55','p56','p57','p58','p59','p60','p61','p62','p63'],
'hospital' : ['h1','h1','h1','h2','h2','h2','h2','h3','h3','h3','h3','h3','h4','h4','h4','h4','h4','h4','h5','h5','h5','h5','h5','h5','h5','h6','h6','h6','h6','h6','h6','h6','h6','h7','h7','h7','h7','h7','h7','h7','h7','h7','h8','h8','h8','h8','h8','h8','h8','h8','h8','h8','h9','h9','h9','h9','h9','h9','h9','h9','h9','h9','h9'],
'region' : ['r1','r1','r1','r1','r1','r1','r1','r1','r1','r1','r1','r1','r2','r2','r2','r2','r2','r2','r2','r2','r2','r2','r2','r2','r2','r2','r2','r2','r2','r2','r2','r2','r2','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3','r3'] }
example_dataframe = pd.DataFrame(example_data)
print example_dataframe
这样会产生一个简单的输出,如下所示:
hospital patient region
0 h1 p1 r1
1 h1 p2 r1
2 h1 p3 r1
3 h2 p4 r1
4 h2 p5 r1
5 h2 p6 r1
6 h2 p7 r1
7 h3 p8 r1
8 h3 p9 r1
9 h3 p10 r1
10 h3 p11 r1
11 h3 p12 r1
12 h4 p13 r2
13 h4 p14 r2
14 h4 p15 r2
15 h4 p16 r2
16 h4 p17 r2
etc.
现在我想用数据透视表来总结一下,简单地统计每个医院的病人数:
example_pivot_table = pd.pivot_table(example_dataframe, values='patient', rows=['hospital','region'], aggfunc='count')
print example_pivot_table
这会产生以下输出:
hospital region
h1 r1 3
h2 r1 4
h3 r1 5
h4 r2 6
h5 r2 7
h6 r2 8
h7 r3 9
h8 r3 10
h9 r3 11
Name: patient, dtype: int64
据我了解,这实际上是一个多重索引的序列。
我该如何使用这些数据来找出医院h7所在的地区呢?如果hospital
、region
和病人数量的数据是数据框中的独立列,那就简单了。但我觉得医院和地区是索引。我尝试了很多方法,但一直没能成功。
3 个回答
这个方法可以解决问题:
levels = example_pivot_table.columns.levels
labels = example_pivot_table.columns.labels
example_pivot_table.columns = levels[1][labels[1]]
example_pivot_table.reset_index(inplace=True)
example_pivot_table
所以,你需要在你的透视表中找到层级和标签,给列命名,并重置索引。最后的结果应该是透视表的结果数据框。
首先,这个问题不是关于透视表的,而是关于 groupby
的。
透视表是用来重新整理数据的,前提是你还没有设置索引(可以参考 这篇文档)。而 stack
和 unstack
是在你已经设置了索引的情况下用来重新整理数据的,groupby
则是用来聚合数据的(这正是我们要做的),还有 分割-应用-合并 操作。
下面是如何使用 groupby
来获取病人数量的方法:
>>> patient_count = df.groupby(['hospital', 'region']).count()
>>> print patient_count
patient
hospital region
h1 r1 3
h2 r1 4
h3 r1 5
h4 r2 6
h5 r2 7
h6 r2 8
h7 r3 9
h8 r3 10
h9 r3 11
如果你想在多重索引中选择某些行,我通常会使用 ix
,方法如下:
>>> h7 = patient_count.ix['h7']
>>> print h7
patient
region
r3 9
现在你可以使用 get_level_values
了。
>>> h7.index.values[0]
'r3'
或者,如果你不想要多重索引的版本(而且对于你的需求来说,可能也不需要),你可以这样做:
>>> patient_count = patient_count.reset_index()
这可以让你找到医院 h7
所在的区域,如下所示:
>>> patient_count.region[patient_count.hospital == 'h7']
6 r3
Name: region, dtype: object
如果你只想要 r3
,你可以这样做:
>>> patient_count.region[patient_count.hospital == 'h7'].values[0]
'r3'
注意,reset_index
这个操作不会在原地进行,这使得它非常适合像这样链式调用方法:
>>> patient_count.ix['h7'].reset_index().region[0]
'r3'
你可以使用 get_level_values 来获取医院这一列。你可以传入级别的编号或者级别的名称,比如 0
或者 hospital
。
然后你可以通过以下方式获取你想要的内容:
In [38]: example_pivot_table[ example_pivot_table.index.get_level_values('hospital') == 'h7' ]
Out[38]:
hospital region
h7 r3 9
Name: patient, dtype: int64
更新
如果你想获取地区信息,可以这样做:
example_pivot_table[ example_pivot_table.index.get_level_values('hospital') == 'h7' ]['regions']