pandas 难以置信的多重索引1——多重索引的构建(史上最全)

本文详细介绍了pandas中的多重索引(分层索引)的创建方法,包括从数组、元组、交叉迭代集和DataFrame构建。通过多索引,可以在二维数据结构中处理高维数据,为数据分析和操作提供了便利。文中还提到了MultiIndex.from_product()、MultiIndex.from_frame()等构造方法,并强调了多索引在分组、选择和重塑操作中的重要性。

分层/多级索引是非常令人兴奋的,因为它为一些相当复杂的数据分析和操作打开了大门,特别是对于处理高维数据。实际上,它使您能够在较低维的数据结构(如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) # 创建耽搁Series试试
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)
一是想和大家交个朋友
二是想帮助朋友们跳过我们遇到的坑,尽快找到解决办法。

======================================================
工作室的运行也需要付出各种成本,“活下去”是我们的当务之急,如果大家有 :

  • 数据分析(报告);
  • 商业数据调研;
  • 数据可视化展示;
  • 数据爬虫;
  • -数据模型开发;
  • 机器学习算法挖掘

  • 也欢迎和我们工作室开展合作~
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Better_Zflyee

交个朋友,多多交流~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值