You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4.2 KiB
4.2 KiB
3.2.2:多级索引的数据转换与累计方法
多级索引行列转换
使用多级索引的关键是掌握有效数据转换的方法,Pandas
提供了许多操作,可以让数据在内容保持不变的同时,按照需要进行行列转换。上一关我们用stack()
和unstack()
演示过简单的行列转换,但其实还有许多合理控制层级行列索引的方法,让我们来一探究竟。
- 有序和无序的索引
如果MultiIndex
不是有序的索引,那么大多数切片操作都会失败,如下例:
# 首先创建一个不按字典顺序排列的多级索引Series
index = pd.MultiIndex.from_product([['a', 'c', 'b'], [1, 2]])
data = pd.Series(np.random.rand(6), index=index)
data.index.names = ['char', 'int']
data
Out:
char int
a 1 0.003001
2 0.164974
c 1 0.741650
2 0.569264
b 1 0.001693
2 0.526226
dtype: float64
# 如果对该多级索引使用局部切片,就会报错
try:
data['a':'b']
except KeyError as e:
print(type(e))
print(e)
Out:
<class 'KeyError'>
'Key length (1) was greater than MultiIndex lexsort depth (0)'
问题是出在MultiIndex
无序排列上,局部切片和许多其他相似的操作都要求MultiIndex
的各级索引是有序的。为此,Pandas
提供了许多便捷的操作完成排序,如sort_index()
和sortlevel()
方法。
data = data.sort_index()
data["a":"b"]
Out:
char int
a 1 0.003001
2 0.164974
b 1 0.001693
2 0.526226
dtype: float64
- 索引stack与unstack
上一节提过,我们可以将一个多级索引数据集转换成简单的二维形式,可以通过level
参数设置转换的索引层级。
pop
Out:
state year
California 2000 33871648
2010 37253956
New York 2000 18976457
2010 19378102
Texas 2000 20851820
2010 25145561
dtype: int64
# level=0
pop.unstack(level=0)
Out:
state California New York Texas
year
2000 33871648 18976457 20851820
2010 37253956 19378102 2514556
# level=1
pop.unstack(level=1)
Out:
year 2000 2010
state
California 33871648 37253956
New York 18976457 19378102
Texas 20851820 25145561
unstack()
是stack()
的逆操作,同时使用这两种方法(pop.unstack().stack())
让数据保持不变。
- 索引的设置与重置
层级数据维度转换的另一种方法是行列标签转换,可以通过reset_index
方法实现。也可以用数据的name
属性为列设置名称:
pop_flat = pop.reset_index(name='population')
pop_flat
Out:
state year population
0 California 2000 33871648
1 California 2010 37253956
2 New York 2000 18976457
3 New York 2010 19378102
4 Texas 2000 20851820
5 Texas 2010 25145561
在解决实际问题的时候,可以使用DataFrame
的set_index
方法将类似这样的原始输入数据的列直接转换成MultiIndex
,返回结果就会是一个带多级索引的DataFrame
。
pop_flat.set_index(['state', 'year'])
Out:
population
state year
California 2000 33871648
2010 37253956
New York 2000 18976457
2010 19378102
Texas 2000 20851820
2010 25145561
多级索引的数据累计方法
Pandas
有一些自带的数据累计方法,比如mean()
、sum()
和max()
。而对于层级索引数据,可以设置参数level
实现对数据子集的累计操作。以体检数据为例:
health_data
Out:
subject Bob Guido Sue
type HR Temp HR Temp HR Temp
year visit
2013 1 31.0 38.7 32.0 36.7 35.0 37.2
2 44.0 37.7 50.0 35.0 29.0 36.7
2014 1 30.0 37.4 39.0 37.8 61.0 36.9
2 47.0 37.8 48.0 37.3 51.0 36.5
如果你需要计算每一年各项指标的平均值,那么可以将参数level
设置为索引year
:
data_mean = health_data.mean(level='year')
data_mean
Out:
subject Bob Guido Sue
type HR Temp HR Temp HR Temp
year
2013 37.5 38.2 41.0 35.85 32.0 36.95
2014 38.5 37.6 43.5 37.55 56.0 36.70
如果再设置axis
参数,就可以对列索引进行类似的累计操作了:
data_mean.mean(axis=1, level='type')
Out:
type HR Temp
year
2013 36.833333 37.000000
2014 46.000000 37.283333