在討論完 pandas.concat() 函式之後,有一個 pandas.Series 物件和 pandas.DataFrame 物件的方法可以達到和 pandas.concat() 函式類似的功能,那就是 pandas.Series.append() 方法和 pandas.DataFrame.append()方法。這兩個 append() 方法可以看做是 pandas.concat() 函式的簡化版,只是這 append() 方法合併資料集的方向永遠是對「列」合併。
但要注意的是 pandas.Series.append() 方法和 pandas.DataFrame.append() 方法並不會添加資料集到原來的 pandas.Series 物件或 pandas.DataFrame 物件,而是另外建立新 pandas.Series 和 pandas.DataFrame 物件。
Pandas 的做法與 Python 可變序列(mutable sequence)中的串列(list)物件型態的 append() 方法不同,Python 裡的 s.append() 方法是直接將新項目添加到原來串列 s 的尾端,也就是說,原來的串列 s 被改變了。
在開始介紹 pandas.Series.append() 方法和 pandas.DataFrame.append() 方法前,我們先載入 pandas 套件。
import pandas as pd
pd.__version__
pandas.Series.append() 方法
pandas.Series.append() 方法的功能是合併兩個或多個 pandas.Series 物件,它回覆的是一個合併後的 pandas.Series 物件。由於 pandas.Series.append() 方法只能「逐列」合併,因此合併後的結果無法像 pandas.concat() 函式可以選擇逐欄合併後形成 pandas.DataFrame 物件。 首先,我們先來看看 pandas.Series.append() 方法有哪些參數。
Series.append(self, to_append, ignore_index = False, verify_integrity = False)
to_append 參數
to_append 參數可以是一個 pandas.Series 物件或是由 pandas.Series 所形成的一個串列或是元祖(tuple)。
ser1 = pd.Series(['Albert', 'Bell', 'Cherry'],
index = [1, 2, 3])
ser1
ser2 = pd.Series(['David', 'Ellen', 'Flora'],
index = [4, 5, 6])
ser2
ser3 = pd.Series(['Glen', 'Hedy', 'Ian'],
index = [5, 6, 7])
ser3
ser1.append(ser2)
ser1
我們可以看到,在合併之後 ser1 仍然保持不變,也就是 ser2 並沒有添加到 ser1 之後,而是另建 pandas.Series 物件。
ser1.append([ser2, ser3])
在這個例子中,一次合併兩個資料集(ser2 和 ser3)到 ser1 資料集中,而 ser2 與 ser3 資料集以串列的方式先組合在一起。
另外,可以在這個例子中發現重複的索引,ser2 和 ser3 資料集都有索引 5 和 6,因此,合併後的資料集 pandas.Series 物件索引 5 和 6 個出現了兩次,這是因為 pandas.Series.append() 方法在預設上是會保留原先 pandas.Series 物件的索引。
to_append 參數以元祖(tuple)的方式列出要被合併的資料集和以串列(list)的方式列出要被合併的資料集,結果是一樣的。
ser1.append((ser2, ser3))
verify_integrity 參數
verify_integrity 參數是一個布林值,預設是 False。
verify_integrity 參數決定是否檢查合併後的新索引(index)有無重複的索引值。當 verify_integrity = False 時,pandas.Series.append() 方法允許合併後的 pandas.Series 物件可以有重複的索引值。而當 verify_integrity = True 時,pandas.Series.append() 方法發現合併後的 pandas.Series 物件有重複的索引值時,會發出 ValueError 告警。
在實際應用時,資料集來源可能來自不同地方,因此索引值是有重複的可能。
try:
ser1.append([ser2, ser3], verify_integrity = True)
except ValueError as err:
print(f"Exception: {err}")
ignore_index 參數
ignore_index 參數是一個布林值,預設是 False。當設定為 True 時,合併後資料集將不使用合併前資料集的索引(index),取而代之的是數字 0、1、2、...。
在某些資料集的應用中,資料集原先的索引並不重要,資料集之間的索引是否有重複也不在意,這時候可以使用 ignore_index 參數,忽略原先的索引值,合併後的新資料集會重新指定索引值。
ser1.append((ser2, ser3), ignore_index = True)
pandas.DataFrame.append() 方法
pandas.DataFrame.append() 方法的功能是逐列合併兩個或以上的 pandas.DataFrame 物件或 pandas.Series 物件形成一個新的 pandas.DataFrame 物件。
在說明 pandas.DataFrame.append() 方法前,我們先看看它有哪些參數。
DataFrame.append(self, other, ignore_index = False, verify_integrity = False, sort = False)
這裡,我們依舊借用 'Python Data Science Handbook' 裡 make_df() 函式定義,方便建立不同的 pandas.DataFrame 物件。
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)
other 參數
other 參數是一個 pandas.DataFrame 物件、pandas.Series 物件、字典型態的物件、或是這些物件所形成的串列。
df1 = make_df(['Albert', 'Bell', 'Cherry'],
[1, 2, 3])
df1
df2 = make_df(['Albert', 'Bell', 'Cherry'],
[4, 5, 6])
df2
df3 = make_df(['Albert', 'Bell', 'Cherry'],
[5, 6, 7])
df3
df1.append(df2)
df1
從這個例子我們發現 df1 資料集在合併前後並沒有不同,也就是說 df2 並沒有添加到 df1 之後,而是另外建立新的 pandas.DataFrame 物件。
df1.append([df2, df3])
df1.append((df2, df3))
pandas.DataFrame.append() 方法可以一次合併兩個以上的 pandas.DataFrame 物件到原 pandas.DataFrame 物件後,這時添加的 pandas.DataFrame 物件以串列(list)或元祖(tuple)方式組成 other 參數。
當 other 參數是 pandas.Series 物件時,要特別注意它必須有名稱、或是 ignore_index = True 才能夠合併,否則會出現 TypeError 的錯誤訊息。
ser1 = pd.Series(['Albert', 'Bell', 'Cherry'],
index = [1, 2, 3])
ser1
try:
df1.append(ser1)
except TypeError as err:
print(f"Exception: {err}")
ser1 = pd.Series(['Albert', 'Bell', 'Cherry'],
index = [1, 2, 3],
name = 'ser1')
ser1
df1.append(ser1)
這個範例和 pandas.concat() 函式設定 join 參數為 'outer' 的結果一樣。對於 ser1 物件,它的索引值 1、2、3 會成為合併後 pandas.DataFrame 物件的新欄名稱(columns),而 ser1 的名稱(name)會成為合併後 pandas.DataFrame 物件的新索引值(index)。
ser1 = pd.Series(['Albert', 'Bell', 'Cherry'],
index = [1, 2, 3])
ser1
df1.append(ser1, ignore_index = True)
當 ser1 沒有設定名稱(name)時,合併時設定 ignore_index 參數為 True,同樣能達到相同的效果。
當 other 參數是字典型態(dict-like)時,這字典型態在使用上卻有點類似 pandas.Series 物件,以一個字典一列的方式添加。
dict4 = {'Albert': 'Albert-4',
'Bell': 'Bell-4',
'Cherry': 'Cherry-4'
}
dict4
dict5 = {'Albert': 'Albert-5',
'Bell': 'Bell-5',
'Cherry': 'Cherry-5'
}
dict5
df1.append([dict4, dict5])
verify_integrity
verify_integrity 參數是一個布林值,預設是 False。
verify_integrity 參數決定是否檢查合併後的新索引(index)有無重複的索引值。當 verify_integrity = False 時,pandas.DataFrame.append() 方法允許合併後的 pandas.DataFrame 物件可以有重複的索引值。而當 verify_integrity = True 時,pandas.DataFrame.append() 方法發現合併後的 pandas.DataFrame 物件有重複的索引值時,會發出 ValueError 告警。
try:
df1.append([df2, df3], verify_integrity = True)
except ValueError as err:
print(f"Exception: {err}")
ignore_index 參數
ignore_index 參數是一個布林值,預設是 False。當設定為 True 時,合併後資料集將不使用合併前資料集的索引(index),取而代之的是數字 0、1、2、...。
在某些資料集的應用中,資料集原先的索引並不重要,資料集之間的索引是否有重複也不在意,這時候可以使用 ignore_index 參數,忽略原先的索引值,合併後的新資料集會重新指定索引值。
df1.append((df2, df3), ignore_index = True)
sort 參數
sort 參數式一個布林值,是在 0.23.0 版新增的參數,預設值是 None,在 1.0.0 版時變更預設值為 False。
在合併資料集時,如果這些資料集的欄名並未完全對其的話,sort 參數設為 True 會對欄排序。
df4 = make_df(['Albert', 'Cherry', 'David', 'Bell'],
[1, 2, 3, 4])
df4
df5 = make_df(['Bell', 'Flora', 'Ellen', 'David'],
[2, 3, 5, 6])
df5
df4.append(df5, sort = False)
在上面這個範例中,因為 sort = False ,因此並不會對欄這個方向排序。
而下面這個範例中,sort = True ,因此資料集合併之後會再對欄排序。
df4.append(df5, sort = True)
參考資料:
- Pandas 官方網站(https://pandas.pydata.org/)
- 'Python Data Science Handbook', Jake VanderPlas
- Python 官方網站(https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range )
老驥 於 2020/5/14
請先 登入 以發表留言。