Pandas 分層索引的具體實踐
Pandas 分層索引

到目前為止,我們主要關(guān)注的是一維和二維數(shù)據(jù),分別存儲在 Pandas 的 Series 和 DataFrame 對象中。但很多時候,存儲更高維度的數(shù)據(jù)——即由多個鍵索引的數(shù)據(jù)——是很有用的。
早期的 Pandas 版本提供了 Panel 和 Panel4D 對象,可以被視為二維 DataFrame 的三維或四維類似物,但在實際使用中它們有些笨重。處理高維數(shù)據(jù)更常見的模式是利用分層索引(也稱為多重索引),在單個索引中包含多個索引層級。通過這種方式,更高維度的數(shù)據(jù)可以緊湊地表示在熟悉的一維 Series 和二維 DataFrame 對象中。
(如果你對具有 Pandas 風(fēng)格靈活索引的真正N維數(shù)組感興趣,可以了解優(yōu)秀的 Xarray 包。)
在本章中,我們將探討 MultiIndex 對象的直接創(chuàng)建;在多重索引數(shù)據(jù)上進(jìn)行索引、切片和統(tǒng)計計算時的注意事項;以及在簡單和分層索引數(shù)據(jù)表示之間轉(zhuǎn)換的實用方法。
我們從標(biāo)準(zhǔn)導(dǎo)入開始:
import pandas as pd import numpy as np
多重索引的 Series
讓我們從思考如何在一維 Series 中表示二維數(shù)據(jù)開始。
為了具體說明,我們將考慮一個數(shù)據(jù)序列,其中每個數(shù)據(jù)點都有一個字符和一個數(shù)字鍵。
糟糕的方式
假設(shè)你想跟蹤兩個不同年份的各州數(shù)據(jù)。利用我們已經(jīng)介紹過的 Pandas 工具,你可能會傾向于直接使用 Python 元組作為鍵:
index = [('California', 2010), ('California', 2020),
('New York', 2010), ('New York', 2020),
('Texas', 2010), ('Texas', 2020)]
populations = [37253956, 39538223,
19378102, 20201249,
25145561, 29145505]
pop = pd.Series(populations, index=index)
pop
(California, 2010) 37253956 (California, 2020) 39538223 (New York, 2010) 19378102 (New York, 2020) 20201249 (Texas, 2010) 25145561 (Texas, 2020) 29145505 dtype: int64
使用這種索引方案,你可以直接根據(jù)元組索引對 Series 進(jìn)行索引或切片:
pop[('California', 2020):('Texas', 2010)]
(California, 2020) 39538223 (New York, 2010) 19378102 (New York, 2020) 20201249 (Texas, 2010) 25145561 dtype: int64
但便利也僅止于此。例如,如果你需要選擇所有 2010 年的數(shù)據(jù),你就需要進(jìn)行一些繁瑣(而且可能很慢)的數(shù)據(jù)處理才能實現(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
這確實得到了想要的結(jié)果,但相比我們已經(jīng)習(xí)慣的 Pandas 切片語法,這種方式不夠簡潔(對于大型數(shù)據(jù)集來說也不夠高效)。
更好的方式:Pandas 的 MultiIndex
幸運的是,Pandas 提供了更好的方法。
我們基于元組的索引本質(zhì)上就是一種初級的多重索引,而 Pandas 的 MultiIndex 類型為我們提供了所需的各種操作。
我們可以如下通過元組創(chuàng)建一個多重索引:
index = pd.MultiIndex.from_tuples(index)
MultiIndex 表示多個索引層級——在本例中為州名和年份——以及為每個數(shù)據(jù)點編碼這些層級的多個標(biāo)簽。
如果我們用這個 MultiIndex 重新索引我們的 series,就可以看到數(shù)據(jù)的分層表示:
pop = pop.reindex(index) pop
California 2010 37253956
2020 39538223
New York 2010 19378102
2020 20201249
Texas 2010 25145561
2020 29145505
dtype: int64
在 Series 的表示中,前兩列顯示了多重索引的值,第三列顯示了數(shù)據(jù)。
請注意,第一列中有些條目是空白的:在這種多重索引的表示中,任何空白條目都表示與上一行相同的值。
現(xiàn)在,如果我們想訪問第二層索引為 2020 的所有數(shù)據(jù),可以使用 Pandas 的切片語法:
pop[:, 2020]
California 39538223 New York 20201249 Texas 29145505 dtype: int64
結(jié)果是一個只包含我們感興趣鍵的單層索引 Series。
這種語法比我們一開始用元組實現(xiàn)的多重索引方案要方便得多(操作效率也高得多)。
接下來我們將進(jìn)一步討論這種針對分層索引數(shù)據(jù)的索引操作。
多重索引作為額外的維度
你可能還注意到:我們其實可以用帶有索引和列標(biāo)簽的普通 DataFrame 來存儲相同的數(shù)據(jù)。
事實上,Pandas 的設(shè)計正是基于這種等價性。unstack 方法可以迅速將一個多重索引的 Series 轉(zhuǎn)換為常規(guī)索引的 DataFrame:
pop_df = pop.unstack() pop_df
| 2010 | 2020 | |
|---|---|---|
| California | 37253956 | 39538223 |
| New York | 19378102 | 20201249 |
| Texas | 25145561 | 29145505 |
自然而然,stack 方法則提供了相反的操作:
pop_df.stack()
California 2010 37253956
2020 39538223
New York 2010 19378102
2020 20201249
Texas 2010 25145561
2020 29145505
dtype: int64
看到這里,你可能會想,為什么我們還要費心使用分層索引呢?
原因很簡單:正如我們能夠利用多重索引在一維的 Series 中操作二維數(shù)據(jù)一樣,我們也可以用它在 Series 或 DataFrame 中操作三維或更多維度的數(shù)據(jù)。
多重索引中的每增加一個層級,就代表數(shù)據(jù)的一個額外維度;利用這一特性,我們可以更靈活地表示各種類型的數(shù)據(jù)。具體來說,我們可能希望為每個州的每一年添加另一列人口統(tǒng)計數(shù)據(jù)(比如 18 歲以下人口);有了 MultiIndex,只需在 DataFrame 中添加一列即可輕松實現(xiàn):
pop_df = pd.DataFrame({'total': pop,
'under18': [9284094, 8898092,
4318033, 4181528,
6879014, 7432474]})
pop_df
| total | under18 | ||
|---|---|---|---|
| California | 2010 | 37253956 | 9284094 |
| 2020 | 39538223 | 8898092 | |
| New York | 2010 | 19378102 | 4318033 |
| 2020 | 20201249 | 4181528 | |
| Texas | 2010 | 25145561 | 6879014 |
| 2020 | 29145505 | 7432474 |
此外,Pandas中的數(shù)據(jù)操作中討論的所有 ufuncs 和其他功能同樣適用于分層索引。
下面我們根據(jù)上述數(shù)據(jù),按年份計算 18 歲以下人口所占比例:
f_u18 = pop_df['under18'] / pop_df['total'] f_u18.unstack()
| 2010 | 2020 | |
|---|---|---|
| California | 0.249211 | 0.225050 |
| New York | 0.222831 | 0.206994 |
| Texas | 0.273568 | 0.255013 |
這使我們能夠輕松快速地操作和探索高維數(shù)據(jù)。
多重索引的創(chuàng)建方法
構(gòu)建多重索引的 Series 或 DataFrame 最直接的方法,就是將兩個或更多索引數(shù)組的列表直接傳遞給構(gòu)造函數(shù)。例如:
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.626833 | 0.939326 |
| 2 | 0.824948 | 0.823318 | |
| b | 1 | 0.953831 | 0.173091 |
| 2 | 0.371334 | 0.779618 |
創(chuàng)建 MultiIndex 的工作是在后臺完成的。
類似地,如果你傳遞一個以合適元組為鍵的字典,Pandas 會自動識別并默認(rèn)使用 MultiIndex:
data = {('California', 2010): 37253956,
('California', 2020): 39538223,
('New York', 2010): 19378102,
('New York', 2020): 20201249,
('Texas', 2010): 25145561,
('Texas', 2020): 29145505}
pd.Series(data)
California 2010 37253956
2020 39538223
New York 2010 19378102
2020 20201249
Texas 2010 25145561
2020 29145505
dtype: int64
盡管如此,有時顯式創(chuàng)建一個 MultiIndex 也是很有用的;接下來我們將介紹幾種實現(xiàn)這一目標(biāo)的方法。
顯式 MultiIndex 構(gòu)造器
為了更靈活地構(gòu)建索引,你可以使用 pd.MultiIndex 類中提供的構(gòu)造方法。
例如,正如我們之前所做的,可以通過簡單的數(shù)組列表(每個層級的索引值)來構(gòu)造一個 MultiIndex:
pd.MultiIndex.from_arrays([['a', 'a', 'b', 'b'], [1, 2, 1, 2]])
MultiIndex([('a', 1),
('a', 2),
('b', 1),
('b', 2)],
)
或者,你可以通過一個元組列表(每個元組給出每個數(shù)據(jù)點的多重索引值)來構(gòu)造它:
pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1), ('b', 2)])
MultiIndex([('a', 1),
('a', 2),
('b', 1),
('b', 2)],
)
你甚至可以通過單個索引的笛卡爾積來構(gòu)造它:
pd.MultiIndex.from_product([['a', 'b'], [1, 2]])
MultiIndex([('a', 1),
('a', 2),
('b', 1),
('b', 2)],
)
類似地,你可以通過直接傳遞 levels(每個層級可用索引值的列表)和 codes(引用這些標(biāo)簽的編碼列表)來使用其內(nèi)部編碼方式構(gòu)造一個 MultiIndex:
pd.MultiIndex(levels=[['a', 'b'], [1, 2]],
codes=[[0, 0, 1, 1], [0, 1, 0, 1]])
MultiIndex([('a', 1),
('a', 2),
('b', 1),
('b', 2)],
)
這些對象中的任何一個都可以作為 index 參數(shù)傳遞給 Series 或 DataFrame 的構(gòu)造函數(shù),或者傳遞給已有 Series 或 DataFrame 的 reindex 方法。
MultiIndex 層級命名
有時候,為 MultiIndex 的各層級命名會很方便。
這可以通過向前面討論過的任意一個 MultiIndex 構(gòu)造器傳遞 names 參數(shù)來實現(xiàn),或者事后設(shè)置索引的 names 屬性也可以:
pop.index.names = ['state', 'year'] pop
state year
California 2010 37253956
2020 39538223
New York 2010 19378102
2020 20201249
Texas 2010 25145561
2020 29145505
dtype: int64
對于更復(fù)雜的數(shù)據(jù)集,這是一種有助于追蹤各索引值含義的實用方法。
列的 MultiIndex
在 DataFrame 中,行和列是完全對稱的,正如行可以有多級索引,列同樣也可以有多級索引。
請看下面這個例子,它模擬了一些(較為真實的)醫(yī)療數(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)建 DataFrame
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 | 39.0 | 36.1 | 36.0 | 37.3 | 25.0 | 37.4 |
| 2 | 43.0 | 36.1 | 33.0 | 38.3 | 37.0 | 37.7 | |
| 2014 | 1 | 60.0 | 36.6 | 9.0 | 36.9 | 37.0 | 37.5 |
| 2 | 43.0 | 37.3 | 24.0 | 37.6 | 41.0 | 34.8 | |
這本質(zhì)上是一個四維數(shù)據(jù),其中維度分別是受試者、測量類型、年份和訪問次數(shù)。
有了這樣的結(jié)構(gòu),我們可以按人的名字索引頂層列,從而獲得只包含該人信息的完整 DataFrame:
health_data['Guido']
| type | HR | Temp | |
|---|---|---|---|
| year | visit | ||
| 2013 | 1 | 36.0 | 37.3 |
| 2 | 33.0 | 38.3 | |
| 2014 | 1 | 9.0 | 36.9 |
| 2 | 24.0 | 37.6 |
多重索引的索引與切片
對 MultiIndex 進(jìn)行索引和切片的設(shè)計非常直觀,如果你將索引看作是增加的維度會更容易理解。
我們將首先介紹對多重索引的 Series 進(jìn)行索引的方法,然后再介紹對多重索引的 DataFrame 對象進(jìn)行索引的方法。
多重索引的 Series
來看我們之前見過的州人口多重索引 Series 示例:
pop
state year
California 2010 37253956
2020 39538223
New York 2010 19378102
2020 20201249
Texas 2010 25145561
2020 29145505
dtype: int64
我們可以通過使用多個索引項來訪問單個元素:
pop['California', 2010]
np.int64(37253956)
MultiIndex 還支持部分索引,即只索引索引中的某一層級。
結(jié)果是另一個 Series,并保留低層級的索引:
pop['California']
year 2010 37253956 2020 39538223 dtype: int64
只要 MultiIndex 已排序,也可以進(jìn)行部分切片:
pop.loc['California':'New York']
state year
California 2010 37253956
2020 39538223
New York 2010 19378102
2020 20201249
dtype: int64
對于已排序的索引,可以通過在第一個索引位置傳遞一個空切片,實現(xiàn)對低層級的部分索引:
pop[:, 2010]
state California 37253956 New York 19378102 Texas 25145561 dtype: int64
其他類型的索引和選擇(詳見數(shù)據(jù)索引與選擇)同樣適用;例如,可以使用布爾掩碼進(jìn)行選擇:
pop[pop > 22000000]
state year
California 2010 37253956
2020 39538223
Texas 2010 25145561
2020 29145505
dtype: int64
花式索引(fancy indexing)同樣適用:
pop[['California', 'Texas']]
state year
California 2010 37253956
2020 39538223
Texas 2010 25145561
2020 29145505
dtype: int64
多重索引的 DataFrame
多重索引的 DataFrame 具有類似的行為。
來看我們之前的醫(yī)療數(shù)據(jù)玩具 DataFrame 示例:
health_data
| subject | Bob | Guido | Sue | ||||
|---|---|---|---|---|---|---|---|
| type | HR | Temp | HR | Temp | HR | Temp | |
| year | visit | ||||||
| 2013 | 1 | 39.0 | 36.1 | 36.0 | 37.3 | 25.0 | 37.4 |
| 2 | 43.0 | 36.1 | 33.0 | 38.3 | 37.0 | 37.7 | |
| 2014 | 1 | 60.0 | 36.6 | 9.0 | 36.9 | 37.0 | 37.5 |
| 2 | 43.0 | 37.3 | 24.0 | 37.6 | 41.0 | 34.8 | |
請記住,在 DataFrame 中列是主要的索引軸,對于多重索引的 Series,所用的語法同樣適用于列。
例如,我們可以通過一個簡單的操作獲取 Guido 的心率數(shù)據(jù):
health_data['Guido', 'HR']
year visit
2013 1 36.0
2 33.0
2014 1 9.0
2 24.0
Name: (Guido, HR), dtype: float64
同樣地,和單層索引的情況一樣,我們可以使用在數(shù)據(jù)索引與選擇中介紹的 loc、iloc 和 ix 索引器。例如:
health_data.iloc[:2, :2]
| subject | Bob | ||
|---|---|---|---|
| type | HR | Temp | |
| year | visit | ||
| 2013 | 1 | 39.0 | 36.1 |
| 2 | 43.0 | 36.1 | |
這些索引器為底層的二維數(shù)據(jù)提供了類似數(shù)組的視圖,但在 loc 或 iloc 中,每個單獨的索引都可以傳遞一個包含多個索引的元組。例如:
health_data.loc[:, ('Bob', 'HR')]
year visit
2013 1 39.0
2 43.0
2014 1 60.0
2 43.0
Name: (Bob, HR), dtype: float64
在這些索引元組中使用切片并不是特別方便;嘗試在元組中創(chuàng)建切片會導(dǎo)致語法錯誤:
health_data.loc[(:, 1), (:, 'HR')]
Cell In[32], line 1
health_data.loc[(:, 1), (:, 'HR')]
^
SyntaxError: invalid syntax
你可以通過顯式構(gòu)建所需的切片(使用 Python 內(nèi)置的 slice 函數(shù))來實現(xiàn)這一點,但在這種情況下,更好的方法是使用 Pandas 專門為此場景提供的 IndexSlice 對象。
例如:
idx = pd.IndexSlice health_data.loc[idx[:, 1], idx[:, 'HR']]
| subject | Bob | Guido | Sue | |
|---|---|---|---|---|
| type | HR | HR | HR | |
| year | visit | |||
| 2013 | 1 | 39.0 | 36.0 | 25.0 |
| 2014 | 1 | 60.0 | 9.0 | 37.0 |
如你所見,有許多方法可以與多重索引的 Series 和 DataFrame 數(shù)據(jù)進(jìn)行交互。正如本書中的許多工具一樣,最好的熟悉方式就是親自嘗試!
重排多重索引
處理多重索引數(shù)據(jù)的關(guān)鍵之一是學(xué)會如何有效地轉(zhuǎn)換數(shù)據(jù)。
有許多操作可以在不丟失任何信息的前提下,重新排列數(shù)據(jù)集,以便進(jìn)行各種計算。
我們在 stack 和 unstack 方法中已經(jīng)簡單見過這種操作,但實際上還有更多方法可以精細(xì)地控制分層索引與列之間的數(shù)據(jù)重排,下面我們將進(jìn)行詳細(xì)探討。
已排序與未排序的索引
前面我曾簡要提到一個注意事項,這里需要特別強調(diào):
許多 MultiIndex 的切片操作如果索引未排序會失敗。
讓我們仔細(xì)看看這個問題。
我們先創(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.252857
2 0.342139
c 1 0.732484
2 0.740275
b 1 0.478320
2 0.624116
dtype: float64
如果我們嘗試對這個索引進(jìn)行部分切片,將會導(dǎo)致錯誤:
try:
data['a':'b']
except KeyError as e:
print("KeyError", e)
KeyError 'Key length (1) was greater than MultiIndex lexsort depth (0)'
雖然從錯誤信息中并不十分清楚,但這實際上是由于 MultiIndex 沒有排序造成的。
出于多種原因,部分切片和其他類似操作要求 MultiIndex 的各層級必須是有序(即字典序)的。
Pandas 提供了許多便捷方法來進(jìn)行這種排序,比如 DataFrame 的 sort_index 和 sortlevel 方法。
這里我們將使用最簡單的 sort_index 方法:
data = data.sort_index() data
char int
a 1 0.252857
2 0.342139
b 1 0.478320
2 0.624116
c 1 0.732484
2 0.740275
dtype: float64
通過這種方式對索引進(jìn)行排序后,部分切片將如預(yù)期般工作:
data['a':'b']
char int
a 1 0.252857
2 0.342139
b 1 0.478320
2 0.624116
dtype: float64
索引的堆疊與反堆疊
如前所述,我們可以將數(shù)據(jù)集從堆疊的多重索引轉(zhuǎn)換為簡單的二維表示,并可選指定要使用的層級:
pop.unstack(level=0)
| state | California | New York | Texas |
|---|---|---|---|
| year | |||
| 2010 | 37253956 | 19378102 | 25145561 |
| 2020 | 39538223 | 20201249 | 29145505 |
pop.unstack(level=1)
| year | 2010 | 2020 |
|---|---|---|
| state | ||
| California | 37253956 | 39538223 |
| New York | 19378102 | 20201249 |
| Texas | 25145561 | 29145505 |
unstack 的反操作是 stack,在這里可以用來恢復(fù)原始的 series:
pop.unstack().stack()
state year
California 2010 37253956
2020 39538223
New York 2010 19378102
2020 20201249
Texas 2010 25145561
2020 29145505
dtype: int64
索引的設(shè)置與重置
重排分層數(shù)據(jù)的另一種方式是將索引標(biāo)簽轉(zhuǎn)換為列,這可以通過 reset_index 方法實現(xiàn)。
對人口字典調(diào)用該方法會得到一個包含 state 和 year 列的 DataFrame,這些信息原本存儲在索引中。
為了更清晰,我們還可以為數(shù)據(jù)列指定名稱,使其在列表示中更易理解:
pop_flat = pop.reset_index(name='population') pop_flat
| state | year | population | |
|---|---|---|---|
| 0 | California | 2010 | 37253956 |
| 1 | California | 2020 | 39538223 |
| 2 | New York | 2010 | 19378102 |
| 3 | New York | 2020 | 20201249 |
| 4 | Texas | 2010 | 25145561 |
| 5 | Texas | 2020 | 29145505 |
一種常見的模式是根據(jù)列的值構(gòu)建 MultiIndex(多重索引)。
這可以通過 DataFrame 的 set_index 方法實現(xiàn),該方法會返回一個具有多級索引的 DataFrame:
pop_flat.set_index(['state', 'year'])
| population | ||
|---|---|---|
| state | year | |
| California | 2010 | 37253956 |
| 2020 | 39538223 | |
| New York | 2010 | 19378102 |
| 2020 | 20201249 | |
| Texas | 2010 | 25145561 |
| 2020 | 29145505 |
在實際操作中,這種類型的重新索引是探索真實世界數(shù)據(jù)集時最有用的模式之一。
總結(jié)
本筆記系統(tǒng)介紹了 Pandas 的分層索引(MultiIndex)及其在 Series 和 DataFrame 中的應(yīng)用。內(nèi)容涵蓋了分層索引的創(chuàng)建方法(如 from_tuples、from_arrays、from_product 等)、索引和切片操作、索引排序、堆疊與反堆疊(stack/unstack)、索引與列之間的轉(zhuǎn)換(reset_index/set_index),以及多重索引在實際數(shù)據(jù)分析中的優(yōu)勢。通過豐富的代碼示例,展示了如何靈活、高效地處理高維數(shù)據(jù),并強調(diào)了分層索引在數(shù)據(jù)探索和處理中的重要作用。
到此這篇關(guān)于Pandas 分層索引的具體實踐的文章就介紹到這了,更多相關(guān)Pandas 分層索引內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于django 數(shù)據(jù)庫遷移(migrate)應(yīng)該知道的一些事
今天小編就為大家分享一篇關(guān)于django 數(shù)據(jù)庫遷移(migrate)應(yīng)該知道的一些事,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05
numpy.ndarray.flatten()函數(shù)的具體使用
本文主要介紹了numpy.ndarray.flatten()函數(shù)的具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
對pycharm代碼整體左移和右移縮進(jìn)快捷鍵的介紹
今天小編就為大家分享一篇對pycharm代碼整體左移和右移縮進(jìn)快捷鍵的介紹,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07
Python 的格式化字符串(f-string)的基本用法詳解
本文將詳細(xì)介紹 f-string 的定義、語法、用法、格式化選項、版本改進(jìn)、性能、適用場景、注意事項及最佳實踐,感興趣的朋友一起看看吧2025-07-07
Python實現(xiàn)對照片中的人臉進(jìn)行顏值預(yù)測
今天給大家?guī)淼氖顷P(guān)于Python實戰(zhàn)的相關(guān)知識,文章圍繞如何用Python實現(xiàn)對照片中的人臉進(jìn)行顏值預(yù)測展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06

