數(shù)據(jù)科學(xué) IPython 筆記本 7.8 分層索引

7.8 分層索引

原文:Hierarchical Indexing

譯者:飛龍

協(xié)議:CC BY-NC-SA 4.0

本節(jié)是《Python 數(shù)據(jù)科學(xué)手冊》(Python Data Science Handbook)的摘錄。

到目前為止祟敛,我們主要關(guān)注一維和二維數(shù)據(jù),分別存儲在 Pandas SeriesDataFrame對象中锅睛。通常,超出此范圍并存儲更高維度的數(shù)據(jù)(即由多于一個(gè)或兩個(gè)鍵索引的數(shù)據(jù))是有用的印蔬。

雖然 Pandas 確實(shí)提供了PanelPanel4D對象,這些對象原生地處理三維和四維數(shù)據(jù)(參見“旁注:面板數(shù)據(jù)”)退唠,實(shí)踐中的更常見模式是利用分層索引(也稱為多重索引)瞧预,在單個(gè)索引中合并多個(gè)索引層次盆驹。通過這種方式召娜,可以在熟悉的一維Series和二維DataFrame對象中,緊湊地表示高維數(shù)據(jù)雅倒。

在本節(jié)中蔑匣,我們將探索MultiIndex對象的直接創(chuàng)建,在對多重索引數(shù)據(jù)執(zhí)行索引校套,切片和計(jì)算統(tǒng)計(jì)數(shù)據(jù)時(shí)的注意事項(xiàng)侨把,以及在數(shù)據(jù)的簡單和分層索引表示之間進(jìn)行轉(zhuǎn)換的有用例程秋柄。

我們以標(biāo)準(zhǔn)導(dǎo)入開始:

import pandas as pd
import numpy as np

多重索引的序列

讓我們首先考慮如何在一維Series中表示二維數(shù)據(jù)。具體而言笨触,我們將考慮數(shù)據(jù)序列旭旭,其中每個(gè)點(diǎn)都有一個(gè)字符和數(shù)字鍵持寄。

不好的方式

假設(shè)你想跟蹤兩個(gè)不同年份的州的數(shù)據(jù)废麻。使用我們已經(jīng)介紹過的 Pandas 工具烛愧,你可能只想使用 Python 元組作為鍵:

index = [('California', 2000), ('California', 2010),
         ('New York', 2000), ('New York', 2010),
         ('Texas', 2000), ('Texas', 2010)]
populations = [33871648, 37253956,
               18976457, 19378102,
               20851820, 25145561]
pop = pd.Series(populations, index=index)
pop

'''
(California, 2000)    33871648
(California, 2010)    37253956
(New York, 2000)      18976457
(New York, 2010)      19378102
(Texas, 2000)         20851820
(Texas, 2010)         25145561
dtype: int64
'''

使用此索引方案,你可以根據(jù)這個(gè)多重索引沧卢,直接對序列索引或切片:

pop[('California', 2010):('Texas', 2000)]

'''
(California, 2010)    37253956
(New York, 2000)      18976457
(New York, 2010)      19378102
(Texas, 2000)         20851820
dtype: int64
'''

但也就這樣了。 例如立磁,如果你需要選擇 2010 年的所有值,則需要進(jìn)行一些混亂(并且可能很慢)的調(diào)整來實(shí)現(xiàn)它:

pop[[i for i in pop.index if i[1] == 2010]]

'''
(California, 2010)    37253956
(New York, 2010)      19378102
(Texas, 2010)         25145561
dtype: int64
'''

這會產(chǎn)生所需的結(jié)果才沧,但不像我們所喜歡的 Pandas 中的切片語法那樣干凈(或?qū)Υ笮蛿?shù)據(jù)集有效)。

更好的方式:Pandas MultiIndex

幸運(yùn)的是岁歉,Pandas 提供了一種更好的方式锅移。
我們的基于元組的索引非剃,本質(zhì)上是一個(gè)基本的多重索引备绽,而 Pandas 的MultiIndex類型為我們提供了我們希望擁有的操作類型恨锚。我們可以從元組創(chuàng)建多重索引,如下所示:

index = pd.MultiIndex.from_tuples(index)
index

'''
MultiIndex(levels=[['California', 'New York', 'Texas'], [2000, 2010]],
           labels=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])
'''

請注意他挎,MultiIndex包含索引的多個(gè)層次 - 在這種情況下雇盖,州名稱和年份,以及編碼這些層次的狸相,每個(gè)數(shù)據(jù)點(diǎn)的多個(gè)標(biāo)簽。

如果我們用這個(gè)MultiIndex重新索引我們的序列瘸右,我們會看到數(shù)據(jù)的分層表示:

pop = pop.reindex(index)
pop

'''
California  2000    33871648
            2010    37253956
New York    2000    18976457
            2010    19378102
Texas       2000    20851820
            2010    25145561
dtype: int64
'''

這里Series表示的前兩列展示了多個(gè)索引值,而第三列展示數(shù)據(jù)龄章。請注意,第一列中缺少某些條目:在多重索引表示中锚贱,任何空白條目都表示與其上方的行相同的值拧廊。

現(xiàn)在來訪問第二個(gè)索引是 2010 的所有數(shù)據(jù)耐量,我們可以簡單地使用 Pandas 切片表示法:

pop[:, 2010]

'''
California    37253956
New York      19378102
Texas         25145561
dtype: int64
'''

結(jié)果是一個(gè)單值索引的數(shù)組滤港,只帶有我們感興趣的鍵山叮。與我們開始使用的自制的基于元組的多重索引解決方案相比,這種語法更方便(并且操作更加高效!)钞翔。我們現(xiàn)在將進(jìn)一步討論分層索引數(shù)據(jù)上的這種索引操作布轿。

作為額外維度的MultiIndex

你可能會注意到其他內(nèi)容:我們可以使用帶有索引和列標(biāo)簽的簡單DataFrame,來輕松存儲相同的數(shù)據(jù)来颤。事實(shí)上汰扭,Pandas 的構(gòu)建具有這種等價(jià)關(guān)系。 unstack()方法會快速將多重索引的Series轉(zhuǎn)換為常規(guī)索引的DataFrame

pop_df = pop.unstack()
pop_df
2000 2010
California 33871648 37253956
New York 18976457 19378102
Texas 20851820 25145561

當(dāng)然福铅,stack()方法提供了相反的操作:

pop_df.stack()

'''
California  2000    33871648
            2010    37253956
New York    2000    18976457
            2010    19378102
Texas       2000    20851820
            2010    25145561
dtype: int64
'''

看到這個(gè)萝毛,你可能想知道為什么我們會糾結(jié)于分層索引。原因很簡單:就像我們能夠使用多重索引本讥,在一維序列中表示二維數(shù)據(jù)一樣,我們也可以用它在SeriesDataFrame中表示更多維的數(shù)據(jù)。

多重索引中的每個(gè)額外層次表示數(shù)據(jù)的額外維度;利用這個(gè)屬性,我們可以更靈活地處理我們可以表示的數(shù)據(jù)類型巢寡。具體而言题诵,我們可能希望,每年為每個(gè)州添加另一列人口統(tǒng)計(jì)數(shù)據(jù)(例如钉赁,18 歲以下的人口); 使用MultiIndex就像在DataFrame中添加另一列一樣簡單:

pop_df = pd.DataFrame({'total': pop,
                       'under18': [9267089, 9284094,
                                   4687374, 4318033,
                                   5906301, 6879014]})
pop_df
total under18
California 2000 33871648 9267089
2010 37253956 9284094
New York 2000 18976457 4687374
2010 19378102 4318033
Texas 2000 20851820 5906301
2010 25145561 6879014

此外式廷,“Pandas 中的數(shù)據(jù)操作”中討論的所有ufunc和其他功能也適用于分層索引蠕趁。根據(jù)以上數(shù)據(jù)术浪,我們在這里按年計(jì)算 18 歲以下人口的比例:

f_u18 = pop_df['under18'] / pop_df['total']
f_u18.unstack()
2000 2010
California 0.273594 0.249211
New York 0.247010 0.222831
Texas 0.283251 0.273568

這使我們能夠輕松快速地操作和探索高維數(shù)據(jù)倔毙。

MultiIndex的創(chuàng)建方法

SeriesDataFrame構(gòu)造多重索引的最簡單方法诉儒,是簡單地將兩個(gè)或多個(gè)索引數(shù)組的列表傳遞給構(gòu)造器该互。 例如:

df = pd.DataFrame(np.random.rand(4, 2),
                  index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
                  columns=['data1', 'data2'])
df
data1 data2
a 1 0.554233 0.356072
2 0.925244 0.219474
b 1 0.441759 0.610054
2 0.171495 0.886688

創(chuàng)建MultiIndex的工作是在后臺完成的。

類似地萝嘁,如果你傳遞一個(gè)帶有適當(dāng)元組作為鍵的字典,Pandas 會自動識別它并默認(rèn)使用MultiIndex

data = {('California', 2000): 33871648,
        ('California', 2010): 37253956,
        ('Texas', 2000): 20851820,
        ('Texas', 2010): 25145561,
        ('New York', 2000): 18976457,
        ('New York', 2010): 19378102}
pd.Series(data)

'''
California  2000    33871648
            2010    37253956
New York    2000    18976457
            2010    19378102
Texas       2000    20851820
            2010    25145561
dtype: int64
'''

然而河爹,顯式創(chuàng)建一個(gè)MultiIndex有時(shí)很有用州丹;我們在這里會看到其中的幾種方法。

MultiIndex顯式構(gòu)造器

為了更靈活地構(gòu)造索引眷唉,你可以使用pd.MultiIndex中提供的類方法構(gòu)造器。例如,正如我們之前所做的那樣计济,你可以從一個(gè)簡單的數(shù)組列表中構(gòu)造MultiIndex,提供每個(gè)層次中的索引值:

pd.MultiIndex.from_arrays([['a', 'a', 'b', 'b'], [1, 2, 1, 2]])

'''
MultiIndex(levels=[['a', 'b'], [1, 2]],
           labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
'''

你可以從元組列表構(gòu)造它燎含,提供每個(gè)點(diǎn)的多重索引值:

pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1), ('b', 2)])

'''
MultiIndex(levels=[['a', 'b'], [1, 2]],
           labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
'''

你甚至可以從單個(gè)索引的笛卡爾積中構(gòu)造它:

pd.MultiIndex.from_product([['a', 'b'], [1, 2]])

'''
MultiIndex(levels=[['a', 'b'], [1, 2]],
           labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
'''

類似地钝诚,你可以通過傳遞levels(列表的列表泽铛,包含每個(gè)級別的可用索引值)和labels(引用這些標(biāo)簽的列表的列表),直接使用其內(nèi)部編碼構(gòu)造MultiIndex

pd.MultiIndex(levels=[['a', 'b'], [1, 2]],
              labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
              
'''
MultiIndex(levels=[['a', 'b'], [1, 2]],
           labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
'''

當(dāng)創(chuàng)建SeriesDataframe時(shí),這些對象中的任何一個(gè)都可以作為index參數(shù)傳遞凯亮,或者傳遞給現(xiàn)有SeriesDataFramereindex方法。

MultiIndex層次名稱

有時(shí)命名MultiIndex的層次很方便葵擎。
這可以通過將names參數(shù)傳遞給上述任何一個(gè)MultiIndex構(gòu)造器谅阿,或者通過在事后設(shè)置索引的names屬性來實(shí)現(xiàn):

pop.index.names = ['state', 'year']
pop

'''
state       year
California  2000    33871648
            2010    37253956
New York    2000    18976457
            2010    19378102
Texas       2000    20851820
            2010    25145561
dtype: int64
'''

在更復(fù)雜數(shù)據(jù)集的情況下,這可能是跟蹤各種索引值含義的有用方法酬滤。

列的MultiIndex

DataFrame中签餐,行和列是完全對稱的,就像行可以有多個(gè)索引層次一樣盯串,列也可以有多個(gè)層次氯檐。考慮以下內(nèi)容体捏,這是一些(有些現(xiàn)實(shí)的)醫(yī)學(xué)數(shù)據(jù)的模型:

# 分層索引和列
index = pd.MultiIndex.from_product([[2013, 2014], [1, 2]],
                                   names=['year', 'visit'])
columns = pd.MultiIndex.from_product([['Bob', 'Guido', 'Sue'], ['HR', 'Temp']],
                                     names=['subject', 'type'])

# 生成一些數(shù)據(jù)
data = np.round(np.random.randn(4, 6), 1)
data[:, ::2] *= 10
data += 37

# 創(chuàng)建數(shù)據(jù)幀
health_data = pd.DataFrame(data, index=index, columns=columns)
health_data

| | 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 |

在這里冠摄,我們看到行和列的多重索引可以非常方便糯崎。這基本上是四維數(shù)據(jù),其中維度是受試者河泳,測量類型沃呢,年份和就診次數(shù)。有了這個(gè)拆挥,我們就可以通過人名來索引頂級列薄霜,并得到一個(gè)完整的DataFrame,其中只包含該人的信息:

health_data['Guido']
type HR Temp
year visit
2013 1 32.0 36.7
2 50.0 35.0
2014 1 39.0 37.8
2 48.0 37.3

對于一些復(fù)雜記錄纸兔,它包含多個(gè)標(biāo)記的測量值惰瓜,并多次跨越許多受試者(人,國家食拜,城市等)鸵熟,使用分層的行和列非常方便副编!

MultiIndex的索引和切片

MultiIndex上的索引和切片設(shè)計(jì)得很直觀负甸,如果你將索引視為添加的維度,它會有所幫助痹届。我們首先看一下多重索引的Series的索引呻待,然后是多重索引的DataFrame

多重索引的序列

考慮一下我們之前看到的队腐,州人口的多重索引的序列:

pop

'''
state       year
California  2000    33871648
            2010    37253956
New York    2000    18976457
            2010    19378102
Texas       2000    20851820
            2010    25145561
dtype: int64
'''

我們可以通過索引多項(xiàng)來訪問單個(gè)元素:

pop['California', 2000]

# 33871648

MultiIndex也支持部分索引蚕捉,或僅索引索引中的一個(gè)層次。結(jié)果是另一個(gè)Series柴淘,持有較低層次的索引:

pop['California']

'''
year
2000    33871648
2010    37253956
dtype: int64
'''

MultiIndex是有序的迫淹,就可以執(zhí)行部分切片(參見“排序和未排序索引”中的討論):

pop.loc['California':'New York']

'''
state       year
California  2000    33871648
            2010    37253956
New York    2000    18976457
            2010    19378102
dtype: int64
'''

對于有序索引,可以通過在第一個(gè)索引中傳遞空切片为严,來在較低層次上執(zhí)行部分索引:

pop[:, 2000]

'''
state
California    33871648
New York      18976457
Texas         20851820
dtype: int64
'''

其他類型的索引和選擇(在“數(shù)據(jù)索引和選擇”中討論)也可以使用敛熬;例如,基于布爾掩碼的選擇:

pop[pop > 22000000]

'''
state       year
California  2000    33871648
            2010    37253956
Texas       2010    25145561
dtype: int64
'''

基于花式索引的選擇也有效:

pop[['California', 'Texas']]

'''
state       year
California  2000    33871648
            2010    37253956
Texas       2000    20851820
            2010    25145561
dtype: int64
'''

多重索引數(shù)據(jù)幀

多重索引的DataFrame的表現(xiàn)類似第股∮γ瘢考慮我們之前的玩具醫(yī)療DataFrame

health_data

| | 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 |

請記住,列在DataFrame中是主要的夕吻,并且用于多重索引的Series的語法適用于列诲锹。例如,我們可以通過簡單的操作恢復(fù) Guido 的心率數(shù)據(jù):

health_data['Guido', 'HR']

'''
year  visit
2013  1        32.0
      2        50.0
2014  1        39.0
      2        48.0
Name: (Guido, HR), dtype: float64
'''

此外涉馅,與單值索引情況一樣归园,我們可以使用“數(shù)據(jù)索引和選擇”中介紹的locilocix索引器稚矿。例如:

health_data.iloc[:2, :2]

| | subject | Bob |
| --- | --- | --- | --- |
| | type | HR | Temp |
| year | visit| | |
| 2013 | 1 | 31.0 | 38.7 |
| | 2 | 44.0 | 37.7 |

這些索引器提供了底層二維數(shù)據(jù)的數(shù)組式的視圖庸诱,但是可以向lociloc中的每個(gè)索引器悬钳,傳遞多個(gè)索引的元組。例如:

health_data.loc[:, ('Bob', 'HR')]

'''
year  visit
2013  1        31.0
      2        44.0
2014  1        30.0
      2        47.0
Name: (Bob, HR), dtype: float64
'''

在這些索引元組中使用切片并不是特別方便偶翅;嘗試在元組中創(chuàng)建切片將導(dǎo)致語法錯(cuò)誤:

health_data.loc[(:, 1), (:, 'HR')]

'''
  File "<ipython-input-32-8e3cc151e316>", line 1
    health_data.loc[(:, 1), (:, 'HR')]
                     ^
SyntaxError: invalid syntax
'''

你可以通過使用 Python 的內(nèi)置slice()函數(shù)默勾,顯式構(gòu)建所需的切片,來解決這個(gè)問題聚谁,但在這種情況下母剥,更好的方法是使用IndexSlice對象,正是由 Pandas 為這種情況提供的形导。

例如:

idx = pd.IndexSlice
health_data.loc[idx[:, 1], idx[:, 'HR']]
subject Bob Guido Sue
type HR HR HR
year visit
2013 1 31.0 32.0 35.0
2014 1 30.0 39.0 61.0

有很多方法可以在多重索引的Series和``DataFrame`中與數(shù)據(jù)進(jìn)行交互环疼,就像本書中的許多工具一樣,熟悉它們的最好方法就是嘗試它們朵耕!

重排多重索引

處理多重索引數(shù)據(jù)的關(guān)鍵之一炫隶,是知道如何有效地轉(zhuǎn)換數(shù)據(jù)。有許多操作將保留數(shù)據(jù)集中的所有信息阎曹,但為了各種計(jì)算的目的重新排列它伪阶。

我們在stack()unstack()方法中看到了一個(gè)簡短的例子,但是還有很多方法处嫌,可以精確控制分層索引和列之間的數(shù)據(jù)重排栅贴,在這里我們將探索他們。

排序和未排序索引

早些時(shí)候熏迹,我們簡要地提到了一個(gè)警告檐薯,但我們應(yīng)該在這里強(qiáng)調(diào)一下。如果索引未排序注暗,多數(shù)MultiIndex切片操作將失敗坛缕。在這里我們來看看。

我們首先創(chuàng)建一些簡單的多重索引數(shù)據(jù)捆昏,其中索引不是按字母順序排序:

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

'''
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
'''

如果我們嘗試對此索引進(jìn)行部分切片赚楚,則會導(dǎo)致錯(cuò)誤:

try:
    data['a':'b']
except KeyError as e:
    print(type(e))
    print(e)

'''
<class 'KeyError'>
'Key length (1) was greater than MultiIndex lexsort depth (0)'
'''

雖然從錯(cuò)誤消息中并不完全清楚,但這是MultiIndex未排序的結(jié)果屡立。由于各種原因直晨,部分切片和其他類似操作要求MultiIndex中的層次是(按字母順序)排序的。

Pandas 提供了許多便利的例程來執(zhí)行這種排序膨俐;例如DataFramesort_index()sortlevel()方法勇皇。我們這里將使用最簡單的sort_index()

data = data.sort_index()
data

'''
char  int
a     1      0.003001
      2      0.164974
b     1      0.001693
      2      0.526226
c     1      0.741650
      2      0.569264
dtype: float64
'''

通過以這種方式排序索引,部分切片將按預(yù)期工作:

data['a':'b']

'''
char  int
a     1      0.003001
      2      0.164974
b     1      0.001693
      2      0.526226
dtype: float64
'''

索引堆疊和解除堆疊

正如我們之前簡要介紹的那樣焚刺,可以將數(shù)據(jù)集從堆疊的多索引轉(zhuǎn)換為簡單的二維表示敛摘,可選擇指定要使用的層次:

pop.unstack(level=0)
state California New York Texas
year
2000 33871648 18976457 20851820
2010 37253956 19378102 25145561
pop.unstack(level=1)
year 2000 2010
state
California 33871648 37253956
New York 18976457 19378102
Texas 20851820 25145561

unstack()的反面是stack(),這里可以用來恢復(fù)原始序列:

pop.unstack().stack()

'''
state       year
California  2000    33871648
            2010    37253956
New York    2000    18976457
            2010    19378102
Texas       2000    20851820
            2010    25145561
dtype: int64
'''

索引設(shè)置和重設(shè)

重排分層數(shù)據(jù)的另一種方法是將索引標(biāo)簽轉(zhuǎn)換為列乳愉;這可以通過reset_index方法完成兄淫。
在人口字典上調(diào)用它將產(chǎn)生一個(gè)帶有stateyear列的DataFrame屯远,包含以前在索引中的信息。
為清楚起見捕虽,我們可以為列表示指定數(shù)據(jù)名稱:

pop_flat = pop.reset_index(name='population')
pop_flat
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

通常處理現(xiàn)實(shí)世界中的數(shù)據(jù)時(shí)慨丐,原始輸入數(shù)據(jù)看起來像這樣,從列值構(gòu)建MultiIndex會有用泄私。這可以通過DataFrameset_index方法完成房揭,它返回一個(gè)多重索引的DataFrame

pop_flat.set_index(['state', 'year'])
population
state year
California 2000 33871648
2010 37253956
New York 2000 18976457
2010 19378102
Texas 2000 20851820
2010 25145561

在實(shí)踐中,遇到真實(shí)數(shù)據(jù)集時(shí)晌端,我發(fā)現(xiàn)這種類型的重索引捅暴,是更有用的模式之一。

多重索引上的數(shù)據(jù)聚合

我們以前看到咧纠,Pandas 有內(nèi)置的數(shù)據(jù)聚合方法蓬痒,比如mean()``,sum()max()漆羔。對于分層索引數(shù)據(jù)梧奢,可以傳遞level``參數(shù),該參數(shù)控制聚合在上面計(jì)算的數(shù)據(jù)子集钧椰。

例如粹断,讓我們回到我們的健康數(shù)據(jù):

health_data

| | 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 |

也許我們想對每年的兩次就診的測量值求平均。 我們可以通過指定我們想要探索的索引層次來實(shí)現(xiàn)嫡霞,在這種情況下是年份:

data_mean = health_data.mean(level='year')
data_mean

| 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 |

通過進(jìn)一步利用axis關(guān)鍵字,我們可以在列上的層次中取平均值:

data_mean.mean(axis=1, level='type')
type HR Temp
year
2013 36.833333 37.000000
2014 46.000000 37.283333

因此希柿,在兩行中诊沪,我們已經(jīng)能夠查詢每年所有就診和所有受試者的平均心率和體溫。這個(gè)語法實(shí)際上是GroupBy函數(shù)的簡寫曾撤,我們將在“聚合和分組”中討論端姚。雖然這是一個(gè)玩具示例,但許多真實(shí)世界的數(shù)據(jù)集具有相似的層次結(jié)構(gòu)挤悉。

旁注:面板數(shù)據(jù)

Pandas 還有一些我們尚未討論的基本數(shù)據(jù)結(jié)構(gòu)渐裸,即pd.Panelpd.Panel4D對象。這些可以分別認(rèn)為是(一維)Series和(二維)DataFrame結(jié)構(gòu)的三維和四維擴(kuò)展装悲。

一旦熟悉了SeriesDataFrame中的數(shù)據(jù)索引和操作昏鹃,PanelPanel4D就相對簡單易用了。特別是诀诊,“數(shù)據(jù)索引和選擇”中討論的ix洞渤,lociloc索引器,很容易擴(kuò)展到這些更高維的結(jié)構(gòu)属瓣。

我們將不會在本文中進(jìn)一步介紹這些面板結(jié)構(gòu)载迄,因?yàn)槲以诖蠖鄶?shù)情況下發(fā)現(xiàn)讯柔,對于更高維數(shù)據(jù)來說,多重索引是更有用且概念上更簡單的表示护昧。另外魂迄,面板數(shù)據(jù)基本上是密集數(shù)據(jù)表示,而多索引基本上是稀疏數(shù)據(jù)表示惋耙。

隨著維度數(shù)量的增加极祸,對于大多數(shù)真實(shí)世界的數(shù)據(jù)集,密集表示可能變得非常低效怠晴。然而遥金,對于特定場合下的應(yīng)用,這些結(jié)構(gòu)可能是有用的蒜田。如果你想了解PanelPanel4D結(jié)構(gòu)的更多信息稿械,請參考“更多資源”中列出的參考資料。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冲粤,一起剝皮案震驚了整個(gè)濱河市美莫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌梯捕,老刑警劉巖厢呵,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異傀顾,居然都是意外死亡襟铭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門短曾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寒砖,“玉大人,你說我怎么就攤上這事嫉拐×ǘ迹” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵婉徘,是天一觀的道長漠嵌。 經(jīng)常有香客問我,道長盖呼,這世上最難降的妖魔是什么儒鹿? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮塌计,結(jié)果婚禮上挺身,老公的妹妹穿的比我還像新娘。我一直安慰自己锌仅,他們只是感情好章钾,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布墙贱。 她就那樣靜靜地躺著,像睡著了一般贱傀。 火紅的嫁衣襯著肌膚如雪惨撇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天府寒,我揣著相機(jī)與錄音魁衙,去河邊找鬼。 笑死株搔,一個(gè)胖子當(dāng)著我的面吹牛剖淀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播纤房,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼纵隔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了炮姨?” 一聲冷哼從身側(cè)響起捌刮,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎舒岸,沒想到半個(gè)月后绅作,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蛾派,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年俄认,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碍脏。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梭依,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出典尾,到底是詐尸還是另有隱情,我是刑警寧澤糊探,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布钾埂,位于F島的核電站,受9級特大地震影響科平,放射性物質(zhì)發(fā)生泄漏褥紫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一瞪慧、第九天 我趴在偏房一處隱蔽的房頂上張望髓考。 院中可真熱鬧,春花似錦弃酌、人聲如沸氨菇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽查蓉。三九已至乌询,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間豌研,已是汗流浹背妹田。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鹃共,地道東北人鬼佣。 一個(gè)月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像霜浴,于是被迫代替她去往敵國和親晶衷。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容