分层/多级索引是非常令人兴奋的,因为它为一些相当复杂的数据分析和操作打开了大门,特别是对于处理高维数据。实际上,它使您能够在较低维的数据结构(如Series (1d)和DataFrame (2d))中存储和操作具有任意维数的数据。
在本节中,我们将展示“分层”索引的确切含义,以及它如何与上面和前面几节中描述的所有panda索引功能集成。稍后,在讨论对数据进行分组、旋转和重塑时,我们将展示一些重要的应用程序,以说明它如何帮助结构化数据以便进行分析。
一、创建多重索引(分层索引)对象
多索引对象是标准索引对象的层次模拟对象,标准索引对象通常在pandas对象中存储axis标签。您可以将MultiIndex看作元组数组,其中每个元组都是唯一的。可以从数组列表(使用MultiIndex.from_arrays())、元组数组(使用MultiIndex.from_tuples())、交叉迭代集(使用MultiIndex.from_product())或DataFrame(使用MultiIndex.from_frame())创建多索引。当向索引构造函数传递一组元组时,它将尝试返回一个多索引。下面的示例演示了初始化多索引的不同方法。
import pandas as pd
import numpy as np
arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],\
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
tuples = list(zip(*arrays))
tuples
'''
[('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')]
'''
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
'''
MultiIndex([('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')],
names=['first', 'second'])
'''
s = pd.Series(np.random.randn(8), index=index)
s
'''
first second
bar one 0.606254
two -1.193545
baz one 1.226008
two 0.486978
foo one 1.469800
two 0.338351
qux one -0.892168
two -0.650476
dtype: float64
'''
当你想要两个迭代中的每一对元素时,使用MultiIndex.from_product()方法会更容易:
这种貌似是最简单的哇,记住pd.MultiIndex.from_product
iterables = [['bar', 'baz', 'foo', 'qux'], ['one', 'two']]
pd.MultiIndex.from_product(iterables, names=['first', 'second'])
'''
MultiIndex([('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')],
names=['first', 'second'])
'''
您还可以使用MultiIndex.from_frame()方法直接从一个DataFrame构造一个多索引。这是MultiIndex.to_frame()的补充方法。
*作者感觉这种是最麻烦的,不过挺检验对多维数组的掌握,建议手打一下 *
df = pd.DataFrame([['bar', 'one'], ['bar', 'two'],['baz', 'one'],['baz', 'two'], ['foo', 'one'], ['foo', 'two'], ['qux', 'one'],['qux', 'two']], columns=['first', 'second'])
pd.MultiIndex.from_frame(df)
'''
MultiIndex([('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')],
names=['first', 'second'])
'''
为了方便,你可以直接将数组列表传递到Series或DataFrame来自动构造一个多索引:
arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])]
arrays
'''
[array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
dtype='<U3'),
array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'],
dtype='<U3')]
'''
s = pd.Series(np.random.randn(8), index=arrays)
s
'''
bar one 0.042885
two 1.075552
baz one -0.437966
two 0.624236
foo one 0.101495
two 0.639600
qux one -0.260703
two -0.881295
dtype: float64
'''
df = pd.DataFrame(np.random.randn(8,4), index=arrays)
df
'''
0 1 2 3
bar one -0.424972 0.567020 0.276232 -1.087401
two -0.673690 0.113648 -1.478427 0.524988
baz one 0.404705 0.577046 -1.715002 -1.039268
two -0.370647 -1.157892 -1.344312 0.844885
foo one 1.075770 -0.109050 1.643563 -1.469388
two 0.357021 -0.674600 -1.776904 -0.968914
qux one -1.294524 0.413738 0.276662 -0.472035
two -0.013960 -0.362543 -0.006154 -0.923061
'''
所有的多索引构造函数都接受一个names参数,该参数存储级别本身的字符串名称。如果没有提供姓名,则不会分配:
df.index.names
'''
FrozenList([None, None])
'''
这个索引可以返回pandas对象的任何轴,索引的级别由您决定:
df = pd.DataFrame(np.random.randn(3,8),index=['A', 'B', 'C'], coolums=index)
df
'''
first bar baz foo qux
second one two one two one two one two
A 0.895717 0.805244 -1.206412 2.565646 1.431256 1.340309 -1.170299 -0.226169
B 0.410835 0.813850 0.132003 -0.827317 -0.076467 -1.187678 1.130127 -1.436737
C -1.413681 1.607920 1.024180 0.569605 0.875906 -2.211372 0.974466 -2.006747
'''
df = pd.DataFrame(np.random.randn(6,6), index=index[:6], columns=index[:6])
df
'''
first bar baz foo
second one two one two one two
first second
bar one -0.410001 -0.078638 0.545952 -1.219217 -1.226825 0.769804
two -1.281247 -0.727707 -0.121306 -0.097883 0.695775 0.341734
baz one 0.959726 -1.110336 -0.619976 0.149748 -0.732339 0.687738
two 0.176444 0.403310 -0.154951 0.301624 -2.179861 -1.369849
foo one -0.954208 1.462696 -1.743161 -0.826591 -0.345352 1.314232
two 0.690579 0.995761 2.396780 0.014871 3.357427 -0.317441
'''
我们已经“分散”了更高级别的索引,以使控制台输出对你来说更容易一些。注意索引的显示方式可以通过pandas.set_options()中的multi_sparse选项来控制:
元组是标签的必备之选
pd.Series(np.random.randn(8), index=tuples)
'''
(bar, one) 0.146193
(bar, two) 0.011110
(baz, one) 0.698768
(baz, two) 0.277018
(foo, one) -0.014839
(foo, two) -0.348363
(qux, one) 0.680304
(qux, two) 0.299718
dtype: float64
'''
多索引很重要的原因是,它允许您执行分组、选择和重塑操作,我们将在下面和文档的后续部分中描述这些操作。正如您将在后面几节中看到的,您会发现自己使用分层索引的数据,而无需自己显式地创建多索引。但是,当从文件加载数据时,您可能希望在准备数据集时生成自己的多索引。
#########################################################
写在最后:
自己和朋友成立了一个工作室——图灵数据科学工作室(VX:DataUpward):
一是想和大家交个朋友;
二是想帮助朋友们跳过我们遇到的坑,尽快找到解决办法。
======================================================
工作室的运行也需要付出各种成本,“活下去”是我们的当务之急,如果大家有 :
- 数据分析(报告);
- 商业数据调研;
- 数据可视化展示;
- 数据爬虫;
- -数据模型开发;
- 机器学习算法挖掘
- …
也欢迎和我们工作室开展合作~
