Pandas 筆記

合併資料集 - 03 append() 物件方法

 

在討論完 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 套件。

In [1]:
import pandas as pd
pd.__version__
Out[1]:
'1.0.3'

 

 

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

In [2]:
ser1 = pd.Series(['Albert', 'Bell', 'Cherry'],
                 index = [1, 2, 3])
ser1
Out[2]:
1    Albert
2      Bell
3    Cherry
dtype: object
In [3]:
ser2 = pd.Series(['David', 'Ellen', 'Flora'],
                 index = [4, 5, 6])
ser2
Out[3]:
4    David
5    Ellen
6    Flora
dtype: object
In [4]:
ser3 = pd.Series(['Glen', 'Hedy', 'Ian'],
                 index = [5, 6, 7])
ser3
Out[4]:
5    Glen
6    Hedy
7     Ian
dtype: object
In [5]:
ser1.append(ser2)
Out[5]:
1    Albert
2      Bell
3    Cherry
4     David
5     Ellen
6     Flora
dtype: object
In [6]:
ser1
Out[6]:
1    Albert
2      Bell
3    Cherry
dtype: object

我們可以看到,在合併之後 ser1 仍然保持不變,也就是 ser2 並沒有添加到 ser1 之後,而是另建 pandas.Series 物件。

In [7]:
ser1.append([ser2, ser3])
Out[7]:
1    Albert
2      Bell
3    Cherry
4     David
5     Ellen
6     Flora
5      Glen
6      Hedy
7       Ian
dtype: object

在這個例子中,一次合併兩個資料集(ser2 和 ser3)到 ser1 資料集中,而 ser2 與 ser3 資料集以串列的方式先組合在一起。

另外,可以在這個例子中發現重複的索引,ser2 和 ser3 資料集都有索引 5 和 6,因此,合併後的資料集 pandas.Series 物件索引 5 和 6 個出現了兩次,這是因為 pandas.Series.append() 方法在預設上是會保留原先 pandas.Series 物件的索引。

to_append 參數以元祖(tuple)的方式列出要被合併的資料集和以串列(list)的方式列出要被合併的資料集,結果是一樣的。

In [8]:
ser1.append((ser2, ser3))
Out[8]:
1    Albert
2      Bell
3    Cherry
4     David
5     Ellen
6     Flora
5      Glen
6      Hedy
7       Ian
dtype: object

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 告警。

在實際應用時,資料集來源可能來自不同地方,因此索引值是有重複的可能。

In [9]:
try:
    ser1.append([ser2, ser3], verify_integrity = True)
except ValueError as err:
    print(f"Exception: {err}")
 
Exception: Indexes have overlapping values: Int64Index([5, 6], dtype='int64')

ignore_index 參數

ignore_index 參數是一個布林值,預設是 False。當設定為 True 時,合併後資料集將不使用合併前資料集的索引(index),取而代之的是數字 0、1、2、...。

在某些資料集的應用中,資料集原先的索引並不重要,資料集之間的索引是否有重複也不在意,這時候可以使用 ignore_index 參數,忽略原先的索引值,合併後的新資料集會重新指定索引值。

In [10]:
ser1.append((ser2, ser3), ignore_index = True)
Out[10]:
0    Albert
1      Bell
2    Cherry
3     David
4     Ellen
5     Flora
6      Glen
7      Hedy
8       Ian
dtype: object

 

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 物件。

In [11]:
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 物件、字典型態的物件、或是這些物件所形成的串列。

In [12]:
df1 = make_df(['Albert', 'Bell', 'Cherry'],
              [1, 2, 3])
df1
Out[12]:
  Albert Bell Cherry
1 Albert-1 Bell-1 Cherry-1
2 Albert-2 Bell-2 Cherry-2
3 Albert-3 Bell-3 Cherry-3
In [13]:
df2 = make_df(['Albert', 'Bell', 'Cherry'],
              [4, 5, 6])
df2
Out[13]:
  Albert Bell Cherry
4 Albert-4 Bell-4 Cherry-4
5 Albert-5 Bell-5 Cherry-5
6 Albert-6 Bell-6 Cherry-6
In [14]:
df3 = make_df(['Albert', 'Bell', 'Cherry'],
              [5, 6, 7])
df3
Out[14]:
  Albert Bell Cherry
5 Albert-5 Bell-5 Cherry-5
6 Albert-6 Bell-6 Cherry-6
7 Albert-7 Bell-7 Cherry-7
In [15]:
df1.append(df2)
Out[15]:
  Albert Bell Cherry
1 Albert-1 Bell-1 Cherry-1
2 Albert-2 Bell-2 Cherry-2
3 Albert-3 Bell-3 Cherry-3
4 Albert-4 Bell-4 Cherry-4
5 Albert-5 Bell-5 Cherry-5
6 Albert-6 Bell-6 Cherry-6
In [16]:
df1
Out[16]:
  Albert Bell Cherry
1 Albert-1 Bell-1 Cherry-1
2 Albert-2 Bell-2 Cherry-2
3 Albert-3 Bell-3 Cherry-3

從這個例子我們發現 df1 資料集在合併前後並沒有不同,也就是說 df2 並沒有添加到 df1 之後,而是另外建立新的 pandas.DataFrame 物件。

In [17]:
df1.append([df2, df3])
Out[17]:
  Albert Bell Cherry
1 Albert-1 Bell-1 Cherry-1
2 Albert-2 Bell-2 Cherry-2
3 Albert-3 Bell-3 Cherry-3
4 Albert-4 Bell-4 Cherry-4
5 Albert-5 Bell-5 Cherry-5
6 Albert-6 Bell-6 Cherry-6
5 Albert-5 Bell-5 Cherry-5
6 Albert-6 Bell-6 Cherry-6
7 Albert-7 Bell-7 Cherry-7
In [18]:
df1.append((df2, df3))
Out[18]:
  Albert Bell Cherry
1 Albert-1 Bell-1 Cherry-1
2 Albert-2 Bell-2 Cherry-2
3 Albert-3 Bell-3 Cherry-3
4 Albert-4 Bell-4 Cherry-4
5 Albert-5 Bell-5 Cherry-5
6 Albert-6 Bell-6 Cherry-6
5 Albert-5 Bell-5 Cherry-5
6 Albert-6 Bell-6 Cherry-6
7 Albert-7 Bell-7 Cherry-7

pandas.DataFrame.append() 方法可以一次合併兩個以上的 pandas.DataFrame 物件到原 pandas.DataFrame 物件後,這時添加的 pandas.DataFrame 物件以串列(list)或元祖(tuple)方式組成 other 參數。

當 other 參數是 pandas.Series 物件時,要特別注意它必須有名稱、或是 ignore_index = True 才能夠合併,否則會出現 TypeError 的錯誤訊息。

In [19]:
ser1 = pd.Series(['Albert', 'Bell', 'Cherry'],
                 index = [1, 2, 3])
ser1
Out[19]:
1    Albert
2      Bell
3    Cherry
dtype: object
In [20]:
try:
    df1.append(ser1)
except TypeError as err:
    print(f"Exception: {err}")
 
Exception: Can only append a Series if ignore_index=True or if the Series has a name
In [21]:
ser1 = pd.Series(['Albert', 'Bell', 'Cherry'],
                 index = [1, 2, 3],
                 name = 'ser1')
ser1
Out[21]:
1    Albert
2      Bell
3    Cherry
Name: ser1, dtype: object
In [22]:
df1.append(ser1)
Out[22]:
  Albert Bell Cherry 1 2 3
1 Albert-1 Bell-1 Cherry-1 NaN NaN NaN
2 Albert-2 Bell-2 Cherry-2 NaN NaN NaN
3 Albert-3 Bell-3 Cherry-3 NaN NaN NaN
ser1 NaN NaN NaN Albert Bell Cherry

這個範例和 pandas.concat() 函式設定 join 參數為 'outer' 的結果一樣。對於 ser1 物件,它的索引值 1、2、3 會成為合併後 pandas.DataFrame 物件的新欄名稱(columns),而 ser1 的名稱(name)會成為合併後 pandas.DataFrame 物件的新索引值(index)。

In [23]:
ser1 = pd.Series(['Albert', 'Bell', 'Cherry'],
                 index = [1, 2, 3])
ser1
Out[23]:
1    Albert
2      Bell
3    Cherry
dtype: object
In [24]:
df1.append(ser1, ignore_index = True)
Out[24]:
  Albert Bell Cherry 1 2 3
0 Albert-1 Bell-1 Cherry-1 NaN NaN NaN
1 Albert-2 Bell-2 Cherry-2 NaN NaN NaN
2 Albert-3 Bell-3 Cherry-3 NaN NaN NaN
3 NaN NaN NaN Albert Bell Cherry

當 ser1 沒有設定名稱(name)時,合併時設定 ignore_index 參數為 True,同樣能達到相同的效果。

當 other 參數是字典型態(dict-like)時,這字典型態在使用上卻有點類似 pandas.Series 物件,以一個字典一列的方式添加。

In [25]:
dict4 = {'Albert': 'Albert-4',
         'Bell': 'Bell-4',
         'Cherry': 'Cherry-4'
        }
dict4
Out[25]:
{'Albert': 'Albert-4', 'Bell': 'Bell-4', 'Cherry': 'Cherry-4'}
In [26]:
dict5 = {'Albert': 'Albert-5',
         'Bell': 'Bell-5',
         'Cherry': 'Cherry-5'
        }
dict5
Out[26]:
{'Albert': 'Albert-5', 'Bell': 'Bell-5', 'Cherry': 'Cherry-5'}
In [27]:
df1.append([dict4, dict5])
Out[27]:
  Albert Bell Cherry
1 Albert-1 Bell-1 Cherry-1
2 Albert-2 Bell-2 Cherry-2
3 Albert-3 Bell-3 Cherry-3
0 Albert-4 Bell-4 Cherry-4
1 Albert-5 Bell-5 Cherry-5

 

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 告警。

 

In [28]:
try:
    df1.append([df2, df3], verify_integrity = True)
except ValueError as err:
    print(f"Exception: {err}")
 
Exception: Indexes have overlapping values: Int64Index([5, 6], dtype='int64')

 

ignore_index 參數

ignore_index 參數是一個布林值,預設是 False。當設定為 True 時,合併後資料集將不使用合併前資料集的索引(index),取而代之的是數字 0、1、2、...。

在某些資料集的應用中,資料集原先的索引並不重要,資料集之間的索引是否有重複也不在意,這時候可以使用 ignore_index 參數,忽略原先的索引值,合併後的新資料集會重新指定索引值。

In [29]:
df1.append((df2, df3), ignore_index = True)
Out[29]:
  Albert Bell Cherry
0 Albert-1 Bell-1 Cherry-1
1 Albert-2 Bell-2 Cherry-2
2 Albert-3 Bell-3 Cherry-3
3 Albert-4 Bell-4 Cherry-4
4 Albert-5 Bell-5 Cherry-5
5 Albert-6 Bell-6 Cherry-6
6 Albert-5 Bell-5 Cherry-5
7 Albert-6 Bell-6 Cherry-6
8 Albert-7 Bell-7 Cherry-7

 

sort 參數

sort 參數式一個布林值,是在 0.23.0 版新增的參數,預設值是 None,在 1.0.0 版時變更預設值為 False。

在合併資料集時,如果這些資料集的欄名並未完全對其的話,sort 參數設為 True 會對欄排序。

In [30]:
df4 = make_df(['Albert', 'Cherry', 'David', 'Bell'],
              [1, 2, 3, 4])
df4
Out[30]:
  Albert Cherry David Bell
1 Albert-1 Cherry-1 David-1 Bell-1
2 Albert-2 Cherry-2 David-2 Bell-2
3 Albert-3 Cherry-3 David-3 Bell-3
4 Albert-4 Cherry-4 David-4 Bell-4
In [31]:
df5 = make_df(['Bell', 'Flora', 'Ellen', 'David'],
              [2, 3, 5, 6])
df5
Out[31]:
  Bell Flora Ellen David
2 Bell-2 Flora-2 Ellen-2 David-2
3 Bell-3 Flora-3 Ellen-3 David-3
5 Bell-5 Flora-5 Ellen-5 David-5
6 Bell-6 Flora-6 Ellen-6 David-6
In [32]:
df4.append(df5, sort = False)
Out[32]:
  Albert Cherry David Bell Flora Ellen
1 Albert-1 Cherry-1 David-1 Bell-1 NaN NaN
2 Albert-2 Cherry-2 David-2 Bell-2 NaN NaN
3 Albert-3 Cherry-3 David-3 Bell-3 NaN NaN
4 Albert-4 Cherry-4 David-4 Bell-4 NaN NaN
2 NaN NaN David-2 Bell-2 Flora-2 Ellen-2
3 NaN NaN David-3 Bell-3 Flora-3 Ellen-3
5 NaN NaN David-5 Bell-5 Flora-5 Ellen-5
6 NaN NaN David-6 Bell-6 Flora-6 Ellen-6

在上面這個範例中,因為 sort = False ,因此並不會對欄這個方向排序。

而下面這個範例中,sort = True ,因此資料集合併之後會再對欄排序。

In [33]:
df4.append(df5, sort = True)
Out[33]:
  Albert Bell Cherry David Ellen Flora
1 Albert-1 Bell-1 Cherry-1 David-1 NaN NaN
2 Albert-2 Bell-2 Cherry-2 David-2 NaN NaN
3 Albert-3 Bell-3 Cherry-3 David-3 NaN NaN
4 Albert-4 Bell-4 Cherry-4 David-4 NaN NaN
2 NaN Bell-2 NaN David-2 Ellen-2 Flora-2
3 NaN Bell-3 NaN David-3 Ellen-3 Flora-3
5 NaN Bell-5 NaN David-5 Ellen-5 Flora-5
6 NaN Bell-6 NaN David-6 Ellen-6 Flora-6

 

參考資料:

  1. Pandas 官方網站(https://pandas.pydata.org/)
  2. 'Python Data Science Handbook', Jake VanderPlas
  3. Python 官方網站(https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range )

 

 

老驥   於 2020/5/14

 

文章標籤
全站熱搜
創作者介紹
創作者 phd.chi 的頭像
phd.chi

maximaChi's blog

phd.chi 發表在 痞客邦 留言(0) 人氣(1,588)