首页Python【Python数据分析】3...

【Python数据分析】39.数据规整——分层索引


本系列文章配套代码获取有以下三种途径:

  • 可以在以下网站查看,该网站是使用JupyterLite搭建的web端Jupyter环境,因此无需在本地安装运行环境即可使用,首次运行浏览器需要下载一些配置文件(大约20M):

https://returu.github.io/Python_Data_Analysis/lab/index.html
链接:https://pan.baidu.com/s/1MYkeYeVAIRqbxezQECHwcA?pwd=mnsj 提取码:mnsj
  • 前往GitHub详情页面,单击 code 按钮,选择Download ZIP选项:
https://github.com/returu/Python_Data_Analysis

根据《Python for Data Analysis 3rd Edition》翻译整理

—————————————————–

分层索引是 pandas 的一个重要特性,它使你能够在一个轴上拥有多个(两个或更多)索引级别。另一种思考方式是,它提供了一种以低维形式处理高维数据的方法。

1.分层索引:

1.1 Series:

让我们从一个简单的例子开始:创建一个以列表的列表或数组作为索引的Series。

 1>>> data = pd.Series(np.random.randn(9),index=[['android','android','android','ios','ios','wp','wp','symbian','symbian'],['htc','google','huawei','iphone6','iphone7','htc','Nokia','Nokia','LG']])
2>>> data
3android  htc        0.010561
4         google    -0.704215
5         huawei     0.154302
6ios      iphone6   -0.695034
7         iphone7   -0.724016
8wp       htc       -0.978071
9         Nokia      0.327960
10symbian  Nokia      0.221268
11         LG        -0.426582
12dtype: float64

可以看到的上面例子是一个以 MultiIndex 作为其索引的 Series 的美化视图。索引显示中的“间隙”表示“使用正上方的标签”。

 1>>> data.index
2MultiIndex([('android',     'htc'),
3            ('android',  'google'),
4            ('android',  'huawei'),
5            (    'ios''iphone6'),
6            (    'ios''iphone7'),
7            (     'wp',     'htc'),
8            (     'wp',   'Nokia'),
9            ('symbian',   'Nokia'),
10            ('symbian',      'LG')],
11           )

分层索引也称为部分索引,允许我们简洁的选择出数据的子集。

 1>>> data["android"]
2htc       0.010561
3google   -0.704215
4huawei    0.154302
5dtype: float64
6
7# 如果试图索引一些没有完全 lexsorted 的索引会报错,需要先进行第二部分提到的重排序操作
8>>> data["android":"symbian"]
9UnsortedIndexError: 'Key length (1) was greater than MultiIndex lexsort depth (0)'
10
11
12>>> data.loc[["android","symbian"]]
13android  htc       0.010561
14         google   -0.704215
15         huawei    0.154302
16symbian  Nokia     0.221268
17         LG       -0.426582
18dtype: float64

在内部层级中进行选择也是被允许的。

1>>> data.loc[: , "huawei"]
2android    0.154302
3dtypefloat64

使用unstack()方法可以将数据在DataFrame中重新排列,使得分层索引在重塑数据和数组透视表操作中经常使用。与unstack()相对应的是stack()方法。

 1>>> data.unstack()
2               LG     Nokia    google       htc    huawei   iphone6   iphone7
3android       NaN       NaN -0.704215  0.010561  0.154302       NaN       NaN
4ios           NaN       NaN       NaN       NaN       NaN -0.695034 -0.724016
5symbian -0.426582  0.221268       NaN       NaN       NaN       NaN       NaN
6wp            NaN  0.327960       NaN -0.978071       NaN       NaN       NaN
7
8>>> data.unstack().stack()
9android  google    -0.704215
10         htc        0.010561
11         huawei     0.154302
12ios      iphone6   -0.695034
13         iphone7   -0.724016
14symbian  LG        -0.426582
15         Nokia      0.221268
16wp       Nokia      0.327960
17         htc       -0.978071
18dtypefloat64

1.2 DataFrame:

在DataFrame中,每个轴都可以拥有分层索引,并且分层的层级可以有名称。如果有名称将会显示在控制台输出中。

 1>>> data = pd.DataFrame(np.arange(12).reshape((43)),
2...                      index=[["a""a""b""b"], [1212]],
3...                      columns=[["android""android""ios"],["HTC""Google""iphone"]])
4
5>>> data
6    android           ios
7        HTC Google iphone
81       0      1      2
9  2       3      4      5
101       6      7      8
11  2       9     10     11
12
13>>> data.index.names = ["key1" ,"key2"]
14>>> data.columns.names = ["platform","device"]
15
16>>> data
17platform  android           ios
18device        HTC Google iphone
19key1 key2
20a    1          0      1      2
21     2          3      4      5
22b    1          6      7      8
23     2          9     10     11

可以通过访问其 nlevels 属性来查看索引有多少级别。

1>>> data.index.nlevels
22

同样,在DataFrame中也可以通过列索引选择列中的数据组。

1>>> data["android"]
2device     HTC  Google
3key1 key2
4a    1       0       1
5     2       3       4
6b    1       6       7
7     2       9      10

一个MultiIndex可以自己创建,然后复用;前面 DataFrame 中具有级别名称的列也可以这样创建:

1>>> pd.MultiIndex.from_arrays([["android","android","ios"],["HTC","Google","iphone"]],
2...                         names=["platform","device"])
3MultiIndex([('android',    'HTC'),
4            ('android''Google'),
5            (    'ios''iphone')],
6           names=['platform''device'])
2.重排序和层级排序:

有时,你可能需要重新排列轴上的层级顺序或按某个特定层级中的值对数据进行排序。 

swaplevel 方法接收两个层级的序号或名称,返回一个层级互换的新对象(但数据未更改)。

 1>>> data
2platform  android           ios
3device        HTC Google iphone
4key1 key2
5a    1          0      1      2
6     2          3      4      5
7b    1          6      7      8
8     2          9     10     11
9
10>>> data.swaplevel('key1','key2')
11platform  android           ios
12device        HTC Google iphone
13key2 key1
141    a          0      1      2
152    a          3      4      5
161    b          6      7      8
172    b          9     10     11
18
19>>> data.swaplevel(0,1)
20platform  android           ios
21device        HTC Google iphone
22key2 key1
231    a          0      1      2
242    a          3      4      5
251    b          6      7      8
262    b          9     10     11

sort_index 方法可以在指定层级(通过设置level选项)对数据进行排序操作。

 1>>> data.sort_index(level=1)
2platform  android           ios
3device        HTC Google iphone
4key1 key2
5a    1          0      1      2
6b    1          6      7      8
7a    2          3      4      5
8b    2          9     10     11
9
10>>> data.swaplevel(0,1).sort_index(level=0)
11platform  android           ios
12device        HTC Google iphone
13key2 key1
141    a          0      1      2
15     b          6      7      8
162    a          3      4      5
17     b          9     10     11

3.按层级进行汇总统计:

通过设置level选项可以按层级进行描述性和汇总性统计操作,另外可以通过设置axis指定操作的轴。

 1>>> data.groupby("key1").sum()
2platform android           ios
3device       HTC Google iphone
4key1
5a              3      5      7
6b             15     17     19
7
8>>> data.groupby(level="platform",axis=1).sum()
9platform   android  ios
10key1 key2
11a    1           1    2
12     2           7    5
13b    1          13    8
14     2          19   11
15
16# 该方式会在未来版本中废弃
17>>> data.sum(level="key1")
18<stdin>:1FutureWarning: Using the level keyword in DataFrame and Series aggregations is deprecated and will be removed in a future version. Use groupby instead. df.sum(level=1) should use df.groupby(level=1).sum().
19platform android           ios
20device       HTC Google iphone
21key1
22a              3      5      7
23b             15     17     19
4.使用 DataFrame 的列进行索引:

想要使用 DataFrame 中的一个或多个列作为行索引并不罕见;或者,你可能希望将行索引移动到 DataFrame 的列中。

这是一个示例 DataFrame:

 1>>> df = pd.DataFrame({"key1":["a""b""b""a""b""a"],
2...                     "key2":range(6),
3...                     "key3":["one""one""two""one""one""two"],
4...                     "key4":[112233222233]})
5>>> df
6  key1  key2 key3  key4
70    a     0  one    11
81    b     1  one    22
92    b     2  two    33
103    a     3  one    22
114    b     4  one    22
125    a     5  two    33

DataFrame 的 set_index 函数将使用其一个或多个列作为索引创建一个新的 DataFrame。

 1>>> df2 = df.set_index(["key1","key3"])
2>>> df2
3           key2  key4
4key1 key3
5a    one      0    11
6b    one      1    22
7     two      2    33
8a    one      3    22
9b    one      4    22
10a    two      5    33

默认情况下,列从 DataFrame 中删除,但您可以通过将 drop=False  传递给 set_index 来保留它们。

1>>> df.set_index(["key1","key3"],drop=False)
2          key1  key2 key3  key4
3key1 key3
4a    one     a     0  one    11
5b    one     b     1  one    22
6     two     b     2  two    33
7a    one     a     3  one    22
8b    one     b     4  one    22
9a    two     a     5  two    33

另一方面,reset_index  set_index 相反;层次索引级别被移动到列中。

1>>> df2.reset_index()
2  key1 key3  key2  key4
30    a  one     0    11
41    b  one     1    22
52    b  two     2    33
63    a  one     3    22
74    b  one     4    22
85    a  two     5    33


本篇文章来源于微信公众号: 码农设计师

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments