暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Python数据分析笔记#8.1 层次化索引

Yuan的学习笔记 2022-01-17
1180




「目录」

数据规整:聚合、合并和重塑

Data Wrangling: Join, Combine, and Reshape

  • 8.1 => 层次化索引

  • 8.2 => 合并数据集

  • 8.3 => 重塑和轴向旋转

第七章终于结束了,来到了第八章,干杯

我把原书第七章剩下一点正则化的部分跳过去了,因为正则化的东西其实有很多,但是原书只讲了一点,并没有着重去讲,因为作者认为不是数据分析的重点,那我也偷懒跳过去吧

本篇笔记主要讲了层次化索引,涉及了下面几个新出现的方法:

  • DataFrame.swaplevel()
  • DataFrame.sum()
  • DataFrame.sort_index()
  • DataFrame.reset_index()


层次化索引

层次化索引(hierarchical indexing)是pandas的一项重要功能,它使我们能在一个轴上拥有多个索引级别

先来看一下层次化索引长什么样子吧:

In [1]: import pandas as pd

In [2]: import numpy as np

In [3]: data = pd.Series(np.random.randn(9), index=[['a''a''a''b''b''c''c''d''d'], [1, 2, 3, 1, 3, 1, 2, 2, 3]])

In [4]: data
Out[4]:
a  1    0.740915
   2   -1.604666
   3    1.236358
b  1    0.307977
   3    1.856143
c  1   -0.243549
   2   -0.924816
d  2   -0.183851
   3   -0.104385
dtype: float64

复制

查看一下data的index属性,它会告诉你这是一个MultiIndex多重索引,levels里第一个是一级索引,第二个是二级索引,codes里的你观察看看。

In [5]: data.index
Out[5]:
MultiIndex(levels=[['a''b''c''d'], [1, 2, 3]],
           codes=[[0, 0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 2, 0, 2, 0, 1, 1, 2]])

复制

选取索引为'b'的子集:

In [6]: data['b']
Out[6]:
1    0.307977
3    1.856143
dtype: float64

复制

选取索引从'b'到'c'的这部分子集:

In [7]: data['b':'c']
Out[7]:
b  1    0.307977
   3    1.856143
c  1   -0.243549
   2   -0.924816
dtype: float64

复制

选取索引为'b'和'd'的子集:

In [8]: data.loc[['b''d']]
Out[8]:
b  1    0.307977
   3    1.856143
d  2   -0.183851
   3   -0.104385
dtype: float64

复制

还可以这么选,选取第二级索引为'2'的子集:

In [9]: data.loc[:, 2]
Out[9]:
a   -1.604666
c   -0.924816
d   -0.183851
dtype: float64

复制

如果对切片熟悉的话,上面那些选取子集的方法应该都不难理解。

对于DataFrame,每条轴都可以有分层索引:

In [13]: frame = pd.DataFrame(np.arange(12).reshape((4,3)), index=[['a','a','b','b'],[1,2,1,2]],columns=[['Ohio','Ohio','Colorado'],['Green','Red','Green']])

In [14]: frame
Out[14]:
     Ohio     Colorado
    Green Red    Green
a 1     0   1        2
  2     3   4        5
b 1     6   7        8
  2     9  10       11

复制

我们可以给每一层都设置名字:

In [15]: frame.index.names = ['key1''key2']

In [16]: frame.columns.names = ['state''color']

In [17]: frame
Out[17]:
state      Ohio     Colorado
color     Green Red    Green
key1 key2
a    1        0   1        2
     2        3   4        5
b    1        6   7        8
     2        9  10       11

复制

选取子集(分组)和以前没多少区别:

In [18]: frame['Ohio']
Out[18]:
color      Green  Red
key1 key2
a    1         0    1
     2         3    4
b    1         6    7
     2         9   10

In [19]: frame['Ohio']['Red']
Out[19]:
key1  key2
a     1        1
      2        4
b     1        7
      2       10
Name: Red, dtype: int32

In [22]: frame['Ohio']['Red']['a']
Out[22]:
key2
1    1
2    4
Name: Red, dtype: int32

In [23]: frame['Ohio']['Red']['a'][1]
Out[23]: 1

复制

用loc函数来选取:

In [24]: frame.loc['a''Ohio']
Out[24]:
color  Green  Red
key2
1          0    1
2          3    4

In [25]: frame.loc['a', ['Ohio''Colorado']]
Out[25]:
state  Ohio     Colorado
color Green Red    Green
key2
1         0   1        2
2         3   4        5

复制


swaplevel

有时我们需要重新调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序。

swaplevel接受两个level级别编号或名称,并返回一个级别互换的新对象,但数据不会发生变化:

In [24]: frame.swaplevel('key1''key2')
Out[24]:
state      Ohio     Colorado
color     Green Red    Green
key2 key1
1    a        0   1        2
2    a        3   4        5
1    b        6   7        8
2    b        9  10       11

复制

sort_index会根据单个level级别的值对数据进行排序,比如下面对'key2'level下的数据进行排序:

In [25]: frame.sort_index(level=1)
Out[25]:
state      Ohio     Colorado
color     Green Red    Green
key1 key2
a    1        0   1        2
b    1        6   7        8
a    2        3   4        5
b    2        9  10       11

复制

swaplevel可以和sort_index一起用,这样就可以在交换顺序后,在指定level下排序了:

In [26]: frame.swaplevel(0, 1).sort_index(level=0)
Out[26]:
state      Ohio     Colorado
color     Green Red    Green
key2 key1
1    a        0   1        2
     b        6   7        8
2    a        3   4        5
     b        9  10       11

复制


sum汇总统计

之前的笔记中已经写过sum方法了,sum中还有一个level选项,用于指定对某条轴上的哪一个级别求和

In [27]: frame
Out[27]:
state      Ohio     Colorado
color     Green Red    Green
key1 key2
a    1        0   1        2
     2        3   4        5
b    1        6   7        8
     2        9  10       11

In [28]: frame.sum(level='key2')
Out[28]:
state  Ohio     Colorado
color Green Red    Green
key2
1         6   8       10
2        12  14       16

复制

在axis=1轴上,在level='color'这一级别上求和:

In [29]: frame.sum(level='color', axis=1)
Out[29]:
color      Green  Red
key1 key2
a    1         2    1
     2         8    4
b    1        14    7
     2        20   10

复制


使用DataFrame的列进行索引

我们还可以把DataFrame的列当作行索引用。

先随便创一个DataFrame:

In [30]: frame = pd.DataFrame({'a':range(7), 'b':range(7, 0, -1), 'c':['one''one''one''two''two''two''two'], 'd':[0,1,2,0,1,2,3]})

In [31]: frame
Out[31]:
   a  b    c  d
0  0  7  one  0
1  1  6  one  1
2  2  5  one  2
3  3  4  two  0
4  4  3  two  1
5  5  2  two  2
6  6  1  two  3

复制

DataFrame的set_index函数会将其一个或多个列转换为行索引,并创建一个新的DataFrame:

In [32]: frame2 = frame.set_index(['c''d'])

In [33]: frame2
Out[33]:
       a  b
c   d
one 0  0  7
    1  1  6
    2  2  5
two 0  3  4
    1  4  3
    2  5  2
    3  6  1

复制

默认情况,被转换为行索引的列会被移除,但通过drop=False可以将其保留下来:

In [34]: frame.set_index(['c''d'], drop=False)
Out[34]:
       a  b    c  d
c   d
one 0  0  7  one  0
    1  1  6  one  1
    2  2  5  one  2
two 0  3  4  two  0
    1  4  3  two  1
    2  5  2  two  2
    3  6  1  two  3

复制

reset_index的功能跟set_index相反:

In [35]: frame2.reset_index()
Out[35]:
     c  d  a  b
0  one  0  0  7
1  one  1  1  6
2  one  2  2  5
3  two  0  3  4
4  two  1  4  3
5  two  2  5  2
6  two  3  6  1

复制

好啦,这篇结束了。

BYE-BYE,下期见!!!


-END-



往期回顾


字符串对象方法




Stay hungry, stay foolish


文章转载自Yuan的学习笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论