你必須要知道的是 pandas.concat() 函式會完完整整的複製所有的資料集,因此反覆呼叫 pandas.concat()函式連續串接資料集會嚴重的影響執行性能。倘若需要串接數個資料集,與其反覆呼叫 pandas.concat() 函式一個一個串接,不如將所有要串接的資料集放進一個串列(list)或字典(dict)中,只呼叫 pandas.concat() 函式一次。
在開始所有程式說明之前,我們先輸入 Pandas 套件。
import pandas as pd
pd.__version__
而為了方便在範例中建立 pandas.DataFrame 物件,我們借用 'Python Data Science Handbook' 裡 make_df() 函式定義。
def make_df(columns, index):
""" DataFrame creator """
data_dict = {c: [str(c) + '-' + str(i) for i in index]
for c in columns}
return pd.DataFrame(data_dict, index)
部分索引
在合併資料集的時候,資料集之間的索引並不完全重複,我們會使用 join 參數包含或排除串接軸之外另一軸的所有索引,但有時候,我們想樣的結果既不是聯集(join = 'outer')也不是交集(join = 'inner'),而是其中一個資料集的索引,這時候我們可以結合 pandas.DataFrame.reindex() 方法來達到目的。
df1 = make_df(['Albert', 'Betty', 'Cherry', 'David'],
[0, 1, 2, 3])
df1
df2 = make_df(['Betty', 'Cherry', 'Fanny', 'Gill'],
[2, 3, 4, 5])
df2
df = pd.concat([df1, df2], axis = 1)
df
df = pd.concat([df1, df2], axis = 1).reindex(df1.index)
df
pandas.DataFrame.reindex() 方法會對 pandas.DataFrame 物件根據指定的參數重新設定新索引,不在新索引值內的資料集部分會被刪除,而新索引值在資料集之中沒有的索引則會被忽略。
在這個範例中,reindex(df1.index) 直接指定新索引值就是 df1 物件的索引值,因此在合併後的資料集中不在 df1 索引中的資料全部會被刪除。
另外一種有相同結果的寫法是,在執行串接之前先將樣被串接的資料集經 reindex(df1.index) 新索引過濾,再執行串接。
df = pd.concat([df1, df2.reindex(df1.index)],
axis = 1)
df
keys 參數的變化
pandas.concat() 函式的 keys 參數實際上有一些特別的用法,他不只是用來指定階層式索引最外層索引的名稱,他還可以用來取但欄位名稱。另外,我們也可以用字典(dict)的用法來替代 keys 參數。
取代欄位 columns 名稱
之前我們說過,keys 參數是在 pandas.concat() 函式建立階層式索引資料集指定最外層索引的名稱,但有一個特別的用法,在使用 pandas.concat() 函式串接 pandas.Series 物件時,keys 參數不是用來建立建立階層式最外層索引的名稱,而是用來指定欄位名稱。
s1 = pd.Series(['Albert', 'Betty', 'Cherry', 'David'],
name = 's1')
s1
s2 = pd.Series(['Ellen', 'Flix', 'Gill', 'Hedy'],
name = 's2')
s2
s3 = pd.Series(['Ivy', 'Jeremy', 'Kent', 'Lara'],
name = 's3')
s3
df = pd.concat([s1, s2, s3], axis = 1)
df
df = pd.concat([s1, s2, s3], axis = 1,
keys = ['group1', 'group2', 'group3'])
df
用字典替代 keys 參數
將要被串接的資料集以字典(dict)的方式傳入 pandas,concat() 函式時,這字典的 keys 會被當作 pandas.concat() 函式的 keys 參數來使用,建立階層式索引結構。
df1 = make_df(['Albert', 'Betty', 'Cherry'],
[0, 1, 2, 3])
df1
df2 = make_df(['David', 'Ellen', 'Flix'],
[0, 1, 2, 3])
df2
df3 = make_df(['Gill', 'Hedy', 'Ivy'],
[0, 1, 2, 3])
df3
df = pd.concat({'x': df1, 'y': df2, 'z': df3},
axis = 1)
df
不過,當使用字典方式傳入要被串接的資料集,字典的 keys 被當作 pandas.concat() 函式的 keys 參數建立階層式索引結構,但在 pandas.concat() 函式中仍然使用 keys 參數,這時,這 keys 參數和參數裡的順序會用來選擇那些欄位群要被串接起來,不在這 keys 參數裡的欄位群將不會被串接起來。
df = pd.concat({'x': df1, 'y': df2, 'z': df3},
axis = 1, keys = ['y', 'x'])
df
參考資料:
1. pandas 官方網站(https://pandas.pydata.org/)
2. 'Python Data Science Handbook', Jake VanderPlas
老驥 於2020/5/11
留言列表