如何将pandas透视表转换为数据框

7 投票
3 回答
25195 浏览
提问于 2025-04-18 00:45

我想用数据透视表来总结一个数据集,然后能够像使用数据框一样访问透视表中的信息。

想象一下,有一个分层的数据集,里面有在医院接受治疗的病人,还有这些医院所在的地区:

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所在的地区呢?如果hospitalregion和病人数量的数据是数据框中的独立列,那就简单了。但我觉得医院和地区是索引。我尝试了很多方法,但一直没能成功。

3 个回答

1

这个方法可以解决问题:

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

所以,你需要在你的透视表中找到层级和标签,给列命名,并重置索引。最后的结果应该是透视表的结果数据框。

3

首先,这个问题不是关于透视表的,而是关于 groupby 的。

透视表是用来重新整理数据的,前提是你还没有设置索引(可以参考 这篇文档)。而 stackunstack 是在你已经设置了索引的情况下用来重新整理数据的,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'
4

你可以使用 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']

撰写回答